1、chrome 进程
最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程
- 浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能
- 渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下
- GPU 进程。其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
- 网络进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程
- 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响
2、Renderer进程
浏览器有5大进程,渲染进程是多线程模式,如下:
页面的渲染,js的执行,事件的循环都在这一进程内进行,该进程下面拥有着多个线程,靠着这些线程共同完成渲染任务
① 图形用户界面GUI渲染线程
负责渲染浏览器界面,包括解析HTML、CSS、构建DOM树、Render树、布局与绘制等
当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行
② JS引擎线程
JS内核,也称JS引擎,负责处理执行javascript脚本
等待任务队列的任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS引擎在运行JS程序
③ 事件触发线程
听起来像JS的执行,但是其实归属于浏览器,而不是JS引擎,用来控制时间循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)
当JS引擎执行代码块如setTimeout时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中
当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理
注意:由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)
④ 定时触发器线程
setInterval与setTimeout所在线程
定时计时器并不是由JS引擎计时的,因为如果JS引擎是单线程的,如果JS引擎处于堵塞状态,那会影响到计时的准确
当计时完成被触发,事件会被添加到事件队列,等待JS引擎空闲了执行
注意:W3C的HTML标准中规定,setTimeout中低与4ms的时间间隔算为4ms
⑤ 异步HTTP请求线程
在XMLHttpRequest在连接后新启动的一个线程
线程如果检测到请求的状态变更,如果设置有回调函数,该线程会把回调函数添加到事件队列,同理,等待JS引擎空闲了执行
3、浏览器每一帧
- [GUI]渲染线程与JS引擎线程互斥
- 浏览器一般1s刷新60次,即每帧大概16ms,每一帧事件如下
【1】接受输入事件
【2】执行事件回调
【3】开始一帧
【4】执行 RAF (RequestAnimationFrame)
【5】页面布局,样式计算
【6】绘制渲染
【7】执行 RIC (RequestIdelCallback)
4、导航流程:从输入URL到页面展示,这中间发生了什么?
- 首先,浏览器进程接收到用户输入的 URL 请求,浏览器进程便将该 URL 转发给网络进程
- 然后,在网络进程中发起真正的 URL 请求
- 接着网络进程接收到了响应头数据,便解析响应头数据,并将数据转发给浏览器进程
- 浏览器进程接收到网络进程的响应头数据之后,发送“提交导航 (CommitNavigation)”消息到渲染进程
- 渲染进程接收到“提交导航”的消息之后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道
- 最后渲染进程会向浏览器进程“确认提交”,这是告诉浏览器进程:“已经准备好接受和解析页面数据了”
- 浏览器进程接收到渲染进程“提交文档”的消息之后,便开始移除之前旧的文档,然后更新浏览器进程中的页面状态
5、chrome渲染过程
-
渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。
-
渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。
-
创建布局树,并计算元素的布局信息。
-
对布局树进行分层,并生成分层树。
-
为每个图层生成绘制列表,并将其提交到合成线程。
-
合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
-
合成线程发送绘制图块命令 DrawQuad 给浏览器进程。
-
浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。
6、 重排 重绘 合成
-
更新了元素的几何属性(重排)
如果你通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑,重排需要更新完整的渲染流水线,所以开销也是最大的
-
更新元素的绘制属性(重绘)
如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。
-
直接合成阶段
我们使用了 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。
欢迎关注我的前端自检清单,我和你一起成长