Chrome 浏览器是如何工作的?(二)
前言: 因为篇幅较长,该内容分为两局部。没看过第一局部的请盲目温习 Chrome 浏览器是如何工作的?(一)
七. 页面绘制 Paint
通过后面几个步骤,此时残缺的页面构造曾经差不多能够绘制了。然而还有一个问题在于 Render 线程还不晓得你是否在某些 DOM 元素 设置了相对定位如 display:absolute、sticky 或者调整了一些元素的 z-index 属性。因为咱们之前说过,绘制 DOM 的时候,Render 是不关怀款式的,所以下一步就是解决这个问题的。
- 这时 Render 过程的主线程 (Main Thread) 会去遍历 Layout Tree 从而绘制出一个绘制记录表(Paint Record),来保障页面绘制的程序不会出错。
- 当主线程遍历实现后,会生成 图层树 Layer Tree。
- 随后 Render 过程的 主线程 会把设计图交付给 合成器线程 ,合成器线程拿着设计图(Layer Tree)和绘制记录表(Paint Record) 将这些信息绘制成人类能够辨认的像素点坐标信息。这个过程被称为 栅格化。Rastering
- 合成器线程 的栅格原理并不是从页面的最顶部始终渲染到最底部的过程。而是将整个页面分为多个图块交给多个 栅格化线程(Raster Thread),相似于下图这样。
- 栅格线程 将每个图块的栅格化信息保留在 GPU 的内存中。
- 当整个页面都栅格化实现后,主线程此时将收集栅格线程生成的 Draw Quads 信息,这些信息记录了每个图块在内存中的地位和每个图块须要在页面的哪个地位渲染的信息。(再通俗易懂一点讲的话,能够这样简略了解
const Draw = x 坐标,y 坐标等绘制信息
) - 依据这些 Draw Quads 的信息,合成器线程 会生成一个 合成器帧 (Compositor Frame)。而后这个合成器帧会通过 IPC(inter process communication)传送给 浏览器过程。就是这个)
- 紧接着 浏览器过程 将合成器帧 传递给 GPU 过程。(不要遗记咱们之前第一篇所说的,浏览器线程负责调度各个过程的单干)
- 最终 GPU 将页面渲染到页面上,祝贺你🎉!经验九九八十一难你终于看到了最终的页面成果。
- 咱们能够在 Chrome 的调试工具下,抉择 Performance 选项卡来发现浏览器绘制的每一帧对应的页面。
八. 重排 (reflow) 和重绘(repaint)
- 此时如果咱们开始滚动页面,合成器线程就会再次生成一个 合成器帧 通过 IPC 传递给浏览器过程,浏览器过程再传递给 GPU , GPU 再次绘制新的一帧,而后出现出新的页面到屏幕上。此时就会从新进行 Layout 当前的所有步骤。这个过程咱们叫做 重排(reflow)。由此可见重排的代价是很大的
- 常见会引发 重排 的动作比方更改 DOM 元素 高度,定位、伪元素等等。(不是本文重点,请自行查阅相干常识)
- 当页面只是简略的更改了背景色彩等动作时,只会触发 款式计算 和绘制 ,并不会进行其它的工作。这个过程咱们叫做 重绘(repaint)
- 从下面的图咱们能够清晰的看到,无论是重排还是重绘都是进行在主线程上的。别忘了还有一重量级选手 JavaScript 也是运行在主线程上的。那么如果在同一时间进行了大量的重绘重排,其中还穿插着 JS 代码的运行,那么就会造成页面的卡顿。“卡”的产生起因咱们持续往下看。
九. 渲染帧数
- 目前咱们支流的显示器帧数都是在 60HZ 以上。也就是说咱们电脑的性能反对显示器在 1000ms 内实现 60 次页面的刷新,(并不是指 F5 刷新的那个刷新 …😂)那么咱们
1000/60=16.7777
能够得出。浏览器必须在 16ms 的距离绘制出新的一帧,能力保障用户感觉“不卡”。 - 进一步解释就是浏览器要在 16ms 内实现一次下图的调度过程,用户能力失去最好的体验。那么当主线程 JS 的代码过于耗时的时候,无奈及时偿还主线程在以便在 16ms 内进行 Layout和 Layer,那么就造成“卡了一下”的景象。(设想打游戏丢帧)
十.Transform 的长处
咱们常常会看到倡议应用 Transform 来代替 top,left 等地位变动属性。其根本原因就是:
Transform 属性实现的动画不会从新 Layout 和 Layer,而是间接运行在 合成器线程 和栅格线程 中的的那也就意味着它不会争夺主线程的应用,也不会影响 JS 代码的执行。
最初感激 B 站 up 主 objtube 的卢克儿 的这期视频,让我通俗易懂的了解了大抵的流程。(🍉文章内局部截图来自于这期视频)