客户端容器
1 浏览器架构
1.1 浏览器架构演进
单进程架构——>多进程架构——>面向服务架构
1.2 浏览器架构-多进程分工
- 浏览器(主进程):主要负责页面展示逻辑,用户交互,子进程管理;包括地址栏、书签、前进、后退、收藏夹。
- GPU进程:负责UI绘制,包含整个浏览器全部UI。
- 网络进程:网络服务进程,负责网络资源加载。
- 标签页(渲染进程):控制tab内的所有内容,将Html、Css和JavaScript转换为用户可交互的网页。
- 插件进程:控制网站运行的插件。
- 其他进程:基础服务
2 渲染进程
2.1 多线程架构
内部是多线程实现,主要负责页面渲染,脚本执行,事件处理,网络请求。
- JS引擎线程:负责解析和执行js程序,我们经常听说得chrome得v8引擎就是跑在js引擎线程上的,其实语言没有单线程多线程之分,因为解释这个语言的线程是单线程;js引擎线程与GUI线程互斥,当浏览器执行JavaScript程序的时候,GUI渲染线程会保存在一个队列当中;直到计算程序执行完成,才会接着执行;如果js的执行时间过长,会影响页面的渲染不连贯,所以我们要尽量控制js的大小。
- GUI渲染线程:负责渲染页面,解析html、css;构建DOM树和渲染树;当界面需要重绘或由于某种操作引发回流时,该线程就会执行。在Javascript引擎运行脚本期间,GUI渲染线程都是处于挂起状态的,也就是说被冻结了。
- 定时触发线程:浏览器计数器并不是由JS引擎计数的,因为JS引擎是单线程的,如果处于阻塞线程状态就会影响计时的准确,因此通过单独线程来计时并触发定时是更为合理的方案。
为什么setTimeout不阻塞后面程序的运行?
因为setTimeout不是由js引擎线程完成的,是由定时器触发线程完成的,所以它们可以同时进行,那么定时器触发线程在这定时任务完成之后会通知事件触发线程往任务队列里添加事件。
- 网络线程:主要负责网络资源加载。在XHR、Fetch等发起请求后新开一个网络线程请求,如果设置了回调函数,在状态变更时,将回调函数放入事件队列,等待js引擎执行。
- 事件触发线程:由宿主环境提供,用于控制事件循环,不断地从事件队列里取出任务执行。
2.2 JS引擎VS渲染引擎
两者相互独立,并通过桥接方式通信。
JS引擎:解析执行js。
渲染引擎:XML解析生成渲染树,显示在屏幕。
3 Chrome运行原理
3.1 如何展示网页?
浏览器地址输入URL后发生了什么:
浏览器主进程先进行输入处理,然后开始导航,读取响应,寻找渲染进程。通过IPC和渲染进程进行通信,找到渲染进程后,渲染进程开始资源加载并执行脚本,然后构建DOM以及渲染树,构建完成后进行布局、绘制、合成并展示完成。
具体流程细节:
输入处理:
1、用户URL框输入内容的后,UI线程会判断输入的是一个URL地址,还是一个query查询条件。
2、如果是URL,直接请求站点资源;如果是query,将输入发送给搜索引擎。
开始导航:
1、当用户按下回车,UI线程通知网络线程发起一个网络请求,来获取站点内容。
2、请求过程中,tab处于loading状态。
读取响应:
1、网络线程接收到HTTP响应后,先检查响应头的媒体类型(MIME Type)
2、如果响应主体是一个HTML文件,浏览器将内容交给渲染进程处理。
3、如果拿到的是其他类型文件,比如zip、exe等,则交给下载管理器处理。
寻找渲染进程:
1、网络线程做完所有检查后,会告知主进程数据已准备完毕,主进程确认后为这个站点寻找一个渲染进程去处理本次导航。
2、主进程通过IPC消息告知渲染进程去处理本次导航。
3、渲染进程开始接收数据并告知主进程自己已开始处理,导航结束,进入文档加载阶段。
渲染进程——资源加载
1、收到主进程的消息后,开始加载HTML文档。
2、除此之外,还需要加载子资源,比如一些图片,css样式文件以及JavaScript脚本。
渲染进程——构建渲染树
1、构建DOM树,将HTML文本转化为浏览器能够理解的结构。
2、构建CSSOM树,浏览器同样不认识CSS,需要将CSS代码转化为可理解的CSSOM。
3、构建渲染树,渲染树是DOM树和CSSOM树的结合。
渲染进程——页面布局
1、根据渲染树计算每个节点的位置和大小
2、在浏览器页面区域绘制元素边框
2、遍历渲染树,将元素以盒模型的形式写入文档流。
渲染进程——页面绘制
1、构建图层
2、绘制图层
3、合成线程接受指令生成图块
4、栅格线程将图块进行栅格化
5、展示在屏幕上
3.2 首屏优化
- 压缩、分包、删除无用代码
- 静态资源分离
- JS脚本非阻塞加载
- 缓存策略
- SSR
- 预置loading、骨架屏
3.3 渲染优化
- GPU加速
- 减少回流、重绘
- 离屏渲染
- 懒加载
3.4 JS优化
- 防止内存泄漏
- 循环尽早break
- 合理使用闭包
- 减少Dom访问
- 防抖(多次提交只执行最后一次的结果)、节流(保证规定时间内多次调用只执行一次)
- web workers
4 跨端容器
4.1 跨端容器 WebView
1、Webview,即网页视图,用于加载网页URL,并展示其内容的控件。
2、可以内嵌在移动端APP内,实现前端混合开发,大多数混合框架都是基于Webview的二次开发;比如Ionic、Cordova。
WebView<->Native 通信
1、JS环境中提供通信的JSBridge
2、Native端提供SDK响应JSBridge发出的调用
3、前端和客户端分别实现对应功能模块