浏览器页面渲染的核心流程

发布时间:2024年01月09日

流程

在这里插入图片描述
先上一张 chrome 浏览器渲染流程图,可以在 performance 面板查看

分为以下几个步骤:

  1. parse HTML:解析 HTML 文本构建 DOM Tree
  2. Recalc Styles:样式计算,计算出每个 DOM 节点的样式
  3. Layout:计算可见元素几何信息 (位置、尺寸) 生成布局树(Layout Tree), 此处便是回流(重排) reflow
  4. update layer tree:对节点进行分层,建立图层树(Layer Tree)
    paint:为每个图层生成绘制列表,并提交到合成线程,合成线程将图层分图块,并栅格化将图块转换成位图(重绘)
  5. Composite Layers:在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上

浏览器渲染原理

在这里插入图片描述

  • DOM 元素与 Layout Object 存在一一对应的关系
  • 一般来说,拥有相同坐标空间的 Layout Object 属于同一个 Paint Layer (渲染层),通过 position、opacity、filterCSS 属性可以创建新的 Paint Layer
  • 某些特殊的 Paint Layer 会被认为是 Composite Layer (合成层/复合层),Composite Layer 拥有单独的 Graphics Layer (图形层),而那些非 Composite LayerPaint Layer,会与拥有 Graphics Layer 的父层共用一个

大多数人对于CSS3的第一印象,就是可以通过3D(如transform)属性来开启硬件加速,许多同学在重构某一个项目时,考虑到动画性能问题,都会倾向将2D属性改为3D属性,但开启硬件加速的底层原理其实就在于将 Paint Layer 提升到了 Composite Layer

渲染层提升为合成层有一个先决条件,该渲染层必须是 SelfPaintingLayer。以下所讨论的渲染层提升为合成层的情况都是在该渲染层为 SelfPaintingLayer 前提下的

  • 3D 或透视变换 (perspective、transform) CSS 属性
  • 使用加速视频解码的 元素
  • 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 元素
  • 混合插件 (如 Flash)
  • 对 opacity、transform、fliter、backdropfilter 应用了 animation 或者 transition(需要是 active 的 animation 或者 transition,当 animation 或者 transition 效果未开始或结束后,提升合成层也会失效)
  • will-change 设置为 opacity、transform、top、left、bottom、right(其中 top、left 等需要设置明确的定位属性,如 relative 等)
  • 拥有加速 CSS 过滤器的元素
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素 (换句话说就是该元素在复合层上面渲染)

3D transform、will-change 设置为 opacity、transform 等 以及 包含 opacity、transform 的 CSS 过渡和动画 这 3 个经常遇到的提升合成层的情况请重点记住

我们可以使用 Chrome DevTools 工具来查看页面中合成层的情况

一种方式是在 Rendering 面板中勾选 Layer borders 选项,页面中的合成层就会被加上黄色边框

在这里插入图片描述
第二种是直接打开 Layers 面板查看,还会显示合成原因
在这里插入图片描述
提升为合成层简单说来有以下几点好处:

  • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快

  • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层

  • 对于 transform 和 opacity 效果,不会触发 layout 和 paint

我们可以利用合成层来优化页面性能

提升动画效果的元素?

合成层的好处是不会影响到其他元素的绘制,因此,为了减少动画元素对其他元素的影响,从而减少 paint,我们需要把动画效果中的元素提升为合成层。

提升合成层的最好方式是使用 CSS 的 will-change 属性。从上一节合成层产生原因中,可以知道 will-change 设置为 opacity、transform、top、left、bottom、right 可以将元素提升为合成层。

#target {
  will-change: transform;
}

参考1:https://cansiny0320.vercel.app/browser-render-process#%E5%90%88%E6%88%90

参考2: https://github.com/AwesomeDevin/blog/issues/39

文章来源:https://blog.csdn.net/weixin_40639095/article/details/135479293
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。