3.1.chrome进程、渲染

368 阅读6分钟

1、chrome 进程

image.png 最新的 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大进程,渲染进程是多线程模式,如下:

image.png
页面的渲染,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,每一帧事件如下 image.png 【1】接受输入事件
    【2】执行事件回调
    【3】开始一帧
    【4】执行 RAF (RequestAnimationFrame)
    【5】页面布局,样式计算
    【6】绘制渲染
    【7】执行 RIC (RequestIdelCallback)

4、导航流程:从输入URL到页面展示,这中间发生了什么?

  1. 首先,浏览器进程接收到用户输入的 URL 请求,浏览器进程便将该 URL 转发给网络进程
  2. 然后,在网络进程中发起真正的 URL 请求
  3. 接着网络进程接收到了响应头数据,便解析响应头数据,并将数据转发给浏览器进程
  4. 浏览器进程接收到网络进程的响应头数据之后,发送“提交导航 (CommitNavigation)”消息到渲染进程
  5. 渲染进程接收到“提交导航”的消息之后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道
  6. 最后渲染进程会向浏览器进程“确认提交”,这是告诉浏览器进程:“已经准备好接受和解析页面数据了”
  7. 浏览器进程接收到渲染进程“提交文档”的消息之后,便开始移除之前旧的文档,然后更新浏览器进程中的页面状态

image.png

5、chrome渲染过程

image.png

  • 渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。

  • 渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。

  • 创建布局树,并计算元素的布局信息。

  • 对布局树进行分层,并生成分层树。

  • 为每个图层生成绘制列表,并将其提交到合成线程。

  • 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。

  • 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。

  • 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

6、 重排 重绘 合成

  • 更新了元素的几何属性(重排)

    如果你通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑,重排需要更新完整的渲染流水线,所以开销也是最大的

  • 更新元素的绘制属性(重绘)

    如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。

  • 直接合成阶段

    我们使用了 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

欢迎关注我的前端自检清单,我和你一起成长