浏览器-重排&&重绘
Jonnzer Lv4

底层原理:

webkit 引擎将 render树上的每个可见元素,包装成 渲染对象 。 而 WebKits RenderObject 类是所有渲染对象的基类。
这个基类,包含了以下两个方法:
(1) layout:
学名:布局 / 回流
功能点:计算位置和大小 (开销最大,回流完需要重绘)

全局布局 && 增量布局

这两个布局改变,都会触发 layout ,重新计算元素位置和大小

  • 全局布局:触发整个 render 树的布局,触发原因可能有:

    • 字体大小
    • 屏幕大小的调整
  • 增量布局:
    触发的原因:请求样式计算

    • 一个 DOM 元素的几何属性变化,常见的几何属性有 width、height、padding、margin、left、top、border 等等。
    • 使 DOM 节点发生增减或者移动。
    • 读写 offset 家族、scroll 家族和 client 家族属性的时候,浏览器为了获取这些值,需要进行回流操作。
    • 调用 window.getComputedStyle 方法。

(2)paint:
学名:重绘

功能点: 在构造render 树和 layout 阶段后,知道可见节点,以及样式和具体大小位置信息(几何信息)后,将每个render 节点转化成屏幕像素的过程。

触发原因:改变了元素外观风格的样式,没影响几何属性
改变 visibility
outline
background-color

绘制顺序:
1. 背景颜色
2. 背景图片
3. 边框
4. 子代
5. 轮廓

(3)回流一定会触发重绘,而重绘不一定发生回流

优化

1 缓存 对几何信息的结果
(现在浏览器对 重绘和回流的优化:浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。)

2 避免频繁操作 DOM
documentFragment

3 开启 GPU 加速
tranlateZ(0) 强制提升层等级

但同时存在缺陷,硬件加速不是万金油,单独创建合成层是有代价的,每创建一个合成层,就要为其分配内存,内存大小取决于复合层的数量。复合层的大小 层的管理也更为复杂,在一些低端和终端移动端设备中更为明显,滥用 GPU 加速会引起页面卡顿甚至闪退。

4 requestAnimationFrame (下次重绘前触发,可传入触发回调函数,优点是能适配屏幕刷新率)

参考:
segment
政采云

  • 本文标题:浏览器-重排&&重绘
  • 本文作者:Jonnzer
  • 创建时间:2020-07-20 18:00:00
  • 本文链接:https://jonnzer.github.io/2020/07/20/重绘&&重排/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论