
- JavaScript:JavaScript 实现动画效果,DOM 元素操作等。
- Style(计算样式):确定每个 DOM 元素应该应用什么 CSS 规则。
- Layout(布局):计算每个 DOM 元素在最终屏幕上显示的大小和位置。由于 web 页面的元素布局是相对的,所以其中任意一个元素的位置发生变化,都会联动的引起其他元素发生变化,这个过程叫 reflow。
- Paint(绘制):在多个层上绘制 DOM 元素的的文字、颜色、图像、边框和阴影等。
- Composite(渲染层合并):按照合理的顺序合并图层然后显示到屏幕上。
浏览器渲染一个页面大致是按照下面这个步骤执行。
- 获取 DOM 并将其分割为多个层(RenderLayer)
- 将每个层栅格化,并独立的绘制进位图中
- 将这些位图作为纹理上传至 GPU
- 复合多个层来生成最终的屏幕图像(终极 layer )。
一些dom会因为一些规则被提升成独立的层(开启 GPU 加速),一旦被独立出来之后,便不会再影响其他dom的布局,因为它改变之后,只是“贴上”了页面。
根据这个优点,我们可以把页面中一些布局经常变换的 dom(动画)提升到独立的层。那么,浏览器在之后的 16ms 中,只需进行下面的几个步骤。
TIPS: chrome devtools 中可以开启 Rendering 中的 Layer borders 查看图层纹理。
其中黄色边框表示该元素有 3d 变换,表示放到一个新的复合层(composited layer)中渲染,蓝色栅格表示正常的 render layer。
目前下面这些因素都会引起Chrome创建合成层:
- 3D 或透视变换(perspective,transform) CSS 属性
- 使用加速视频解码的video元素
- 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 canvas 元素
- 混合插件(如 Flash)
- 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
- 拥有加速 CSS 过滤器的元素
- 元素A有一个 z-index 比自己小的元素B,且元素B是一个合成层(换句话说就是该元素在复合层上面渲染),则元素A会提升为合成层
上面6点都非常容易理解,在日常开发中,最容易出现问题的是第7点
CSS属性
浏览器在处理下面的 css 的时候,会使用 gpu 渲染:
- transform
- opacity
- filter
- will-change
https://segmentfault.com/a/1190000008015671
https://csstriggers.com/
https://www.zoo.team/article/browser-redraw