什么是重排和重绘?
当DOM的样式或内容会被修改时,将触发重新渲染。除了属性值计算、单位换算外,渲染主要分为三个步骤:
-
布局:计算盒模型的位置,大小
-
绘制:填充盒模型的文字、颜色、图像、边框和阴影等可视效果
-
合并:所有图层绘制后,按层叠顺序合并为一个图层 重新渲染一般有三种执行路径:
-
重排:布局 → 绘制 → 合并
-
重绘:绘制 → 合并
-
合并 不同属性的修改,会触发不同的渲染路径
更改哪些属性会触发重排和重绘?
引起重排的属性,即布局类属性,包括:
类型 | 属性名 |
---|---|
盒模型 | display padding margin width height min-height max-height border border-width |
定位和浮动 | position top bottom left right float clear |
文字及溢出 | font-family font-size font-weight line-height text-align vertical-align white-space overflow overflow-y |
引起重绘的属性,即绘制类属性,包括:
类型 | 属性名 |
---|---|
颜色 | color |
边框 | border-color border-style border-radius |
背景 | background background-image background-position background-repeat background-size |
轮廓 | outline outline-color outline-style outline-width |
可见性 | visibility |
文字方向 | text-decoration |
发光 | box-shadow |
如何避免重排和重绘?
- 尽量使用仅引起合成的属性
类型 | 属性名 |
---|---|
变形 | transform |
透明度 | opacity |
-
限制重新渲染区域
- 使用
position:absolute
或position:fixed
等方法创建层叠上下文 - 使用
contain:layout
或contain:paint
等属性值,让当前元素和内容独立于 DOM 树 - 减少使用
display:table
或<table>
表格布局
- 使用
-
利用浏览器自身优化
引起回流、重绘的属性操作会放入队列,达到一定数量或时间,再一次渲染
- 用变量缓存元素的属性值
- 要设置的属性值减少依赖其它属性值
- 避免频繁读取计算属性值
-
手动一次渲染
强制使用
style.cssText
或setAttribute('style', 样式)
将所有设置的属性,一次写入内联样式 -
优化 DOM 树
- 使用文档碎片或
display:none
隐藏节点,缓存要插入的节点,之后将缓存结果一次性插入 DOM 树并显示 - 使用
replaceChild``cloneNode
减少先删除、创建再插入 DOM 的场景
- 使用文档碎片或