5分钟带你看完浏览器渲染流程

1. 概念

概念/术语 定义
DOM (文档对象模型) HTML文档的内部树状结构,表示元素及其关系
CSSOM (CSS对象模型) CSS规则的结构化表示
计算样式 (Computed Style) 每个节点的最终样式
布局树 (Layout Tree) 基于DOM和样式计算出的视觉结构,用于确定位置和大小。
绘制记录 (Paint Records) 描述如何绘制元素的指令。
合成 (Compositing) 将多个图层组合成最终屏幕图像的过程。
图层 (Layers) 可独立更新的页面部分,某些元素(如position: fixed)会创建独立图层。
瓦片 (Tiles) 页面的小块区域,便于光栅化和缓存,提升渲染效率。
光栅化 (Rasterization) 将矢量图形转为位图
重新布局 (Reflow) 因DOM或CSS更改触发的布局重新计算,可能影响性能。
重绘 (Repaint) 当元素外观更改时,重新绘制部分页面。
GPU加速 (GPU Acceleration) 使用图形处理单元加速渲染任务,提升复杂图形和动画性能。
Draw Quad Draw Quad(绘制四边形)是合成线程(Compositor Thread)在将页面内容渲染到屏幕上时使用的一种核心概念。它本质上是一个绘制指令,表示将某个特定的图像区域(通常是光栅化后的位图或纹理)绘制到屏幕上的某个位置。Draw Quad 是合成阶段的一个关键中间产物,用于将多个图层(Layers)和瓦片(Tiles)组合成最终的屏幕图像

2. 测试工具

chorme Performance

webpagetest:在资源URL左侧用橙色圆圈标记渲染阻塞资源

3. 工作原理和过程

3.1. 浏览器架构

3.1.1. 浏览器架构

  • Browser Process: 控制应用程序的"chrome"部分,包括地址栏、书签、后退和前进按钮。还处理网络浏览器中不可见的部分,例如网络请求和文件访问
  • Render Process: Controls anything inside of the tab where a website is displayed

3.1.2. 多进程的好处

每个选项卡的都开一个渲染进程,当一个进程没有响应时,不会影响其他选项卡内容的渲染

3.1.3. 节省更多内存-Chrome中的服务化

当 Chrome 在强大的硬件上运行时,它可能会将每个服务拆分为不同的进程以提供更高的稳定性,但如果它在资源受限的设备上,Chrome 会将服务整合到一个进程中以节省内存占用

3.1.4. Per-frame renderer processes -Site isolation

Site isolation为每个站点iframe运行单独的渲染器进程。同源策略是网络的核心安全模型,它确保一个站点在未经同意的情况下无法访问其他站点的数据

3.2. 渲染流程

渲染器进程负责选项卡内的所有工作,最终产物流程如下

3.2.1. 解析HTML(DOM tree)

  1. 主线程(Main Thread)开始解析并构建文档对象模型(DOM)->DOM Tree
  1. 预加载扫描器(Preload Scanner)
  1. 主线程在解析HTML的同时,运行一个轻量级的预加载扫描器。

    • 扫描器识别并提前加载子资源
  2. 优化加载优先级

  1. DOM树是后续渲染的基础,预加载扫描器通过并行加载资源减少等待时间

3.2.2. 样式计算(DOM tree+CSSOM->Composer tree)

CSSOM与DOM树共同决定了页面的视觉表现,计算样式是布局的基础

  1. CSS解析

    • 主线程读取CSS文件(包括外部CSS、内联样式和标签中的样式)。
    • CSS解析器将CSS代码转换为样式表对象(CSSOM,CSS Object Model)

即使不添加样式,dom结构自己也有默认样式

  1. 计算样式(Computed Style)
  2. 主线程遍历DOM树,为每个节点匹配CSS规则,计算最终样式->composer tree

3.2.3. 布局(composer tree=>layout tree)

有了DOM树和计算样式,浏览器进入布局阶段,生成布局树并计算元素的位置和大小,详细了解这部分内容可以阅读这里,布局树定义了页面元素的最终位置和大小,是绘制的前提

  1. 布局树(Layout Tree)构建
    • 布局树基于DOM树和CSSOM,但有所筛选:

    • 排除display: none的元素(完全不可见)。

    • 包括伪元素(如p::before { content: "Hi!"; })。

    • 布局树节点对应于页面的视觉结构

  1. 盒模型计算
  2. 位置和大小计算

3.2.4绘制(layout tree->Paint Records)

布局完成后,浏览器生成绘制指令,准备将页面内容渲染到屏幕上,绘制阶段将布局树的视觉信息转化为像素级的渲染指令

  1. 生成绘制记录(Paint Records)
  2. 绘制顺序由z-index和堆叠上下文(Stacking Context)决定
  1. 性能影响

    • 绘制是CPU密集型任务,频繁更新(如动画)可能导致性能问题。 -浏览器的目标是保持60帧每秒(16.6ms/帧),若主线程被JavaScript阻塞,可能导致卡顿

####3.2.5. 合成

绘制完成后,主线程将任务移交给合成线程(Compositor Thread),完成最终图像的生成和显示

  1. 提交绘制记录

    • 主线程将绘制记录提交给合成线程,释放自身以处理其他任务
  2. 图层(Layers):合成线程将页面分成多个图层

  3. 瓦片(Tiles):每个图层被进一步分成小块(瓦片),通常为256x256或512x512像素。

    • 瓦片化便于缓存和并行处理
  1. 光栅化(Rasterization:合成线程将瓦片转换为位图(Bitmap),并存储到GPU内存中

    • GPU加速的光栅化显著提升性能
  2. 生成Draw Quad:合成线程为每个瓦片创建 Draw Quad,指定其纹理和屏幕坐标

    • 考虑图层间的叠放顺序和透明度
  1. 显示(Viz组件)

    • 合成线程将 Draw Quad 列表发送给浏览器进程的 Viz 组件,Viz 组件利用 GPU 将 Draw Quad 渲染为最终图像,显示在屏幕上。
    • 为加快初次渲染,Viz可能先显示低分辨率图像,随后替换为高质量版本

4. 实践

4.1. 非快速滚动区域的优化

事件委托会将目标元素区域都标记为非快速滚动区域,这样合成器线程每次都要等待主线程工作后才会工作,就丧失了流畅的用户体验,可以通过在监听事件加passive:true解决,这向浏览器提示您仍想在主线程中收听事件,但合成器也可以继续合成新帧

csharp 复制代码
document.body.addEventListener('touchstart', event => {
    if (event.target === area) {
        event.preventDefault()
    }
 }, {passive: true});

4.2. 获取完整的事件触发

对于大多数 Web 应用程序,合并事件应该足以提供良好的用户体验。但是,如果您正在构建诸如绘图应用程序并根据 touchmove坐标放置路径之类的东西,则可能会丢失中间坐标以绘制平滑线。在这种情况下,可以使用getCoalescedEvents指针事件中的方法来获取有关这些合并事件的信息

csharp 复制代码
window.addEventListener('pointermove', event => {
    const events = event.getCoalescedEvents();
    for (let event of events) {
        const x = event.pageX;
        const y = event.pageY;
        // draw a line using x and y coordinates.
    }
});

5. 参考

相关推荐
好_快2 分钟前
Lodash源码阅读-arrayFilter
前端·javascript·源码阅读
若云止水6 小时前
ngx_conf_handler - root html
服务器·前端·算法
佚明zj6 小时前
【C++】内存模型分析
开发语言·前端·javascript
知否技术7 小时前
ES6 都用 3 年了,2024 新特性你敢不看?
前端·javascript
最初@8 小时前
el-table + el-pagination 前端实现分页操作
前端·javascript·vue.js·ajax·html
知否技术9 小时前
JavaScript中的闭包真的过时了?其实Vue和React中都有用到!
前端·javascript
Bruce_Liuxiaowei9 小时前
基于Flask的防火墙知识库Web应用技术解析
前端·python·flask
zhu_zhu_xia9 小时前
vue3中ref和reactive的差异分析
前端·javascript·vue.js
拉不动的猪9 小时前
刷刷题45 (白嫖xxx面试题1)
前端·javascript·面试
幼儿园技术家9 小时前
使用SPA单页面跟MPA多页面的优缺点?
前端