重排会导致重绘,重绘不会导致重排 。
中文环境下面的 重排 会有另外一种称呼方式叫做 回流
。以前一直不理解为什么重排叫回流(直译的 reflow
),导致我在记忆的过程中我总是会把他们混在一起,分不清回流是重排还是重绘。
他们对应的含义我倒是分的还是比较清楚的。简单来说就是,牵扯页面布局的页面更新是重排,重绘就只是一些不影响布局的样式更新……
💥 触发机制
重排的触发机制我归类为以下三类:
- 视窗大小发生改变;
- DOM的操作(可见元素);
- 元素几何样式和定位方式被改变;
- 部分获取元素属性和API的调用;
视窗大小发生改变 和 DOM的操作 都很容易理解,可视区域的改变、DOM元素的增/删/改都会触发重排。
需要注意的是 元素几何样式的改变 和 获取元素属性和API的调用 这两块。
1. 元素几何样式的改变
元素宽高和位置这些属性的变更肯定会触发重排,但是修改字体和字号也是会触发重排的。因为会改变容器的宽高,从而影响到页面布局。
2. 部分获取元素属性和API的调用
分为两类,一类是访问特定属性,比如说获取元素的盒模型信息。
一类是API的访问,例如 getClientRects()
、scrollTo()
、、getComputedStyle()
这类API,它们会访问某个元素尺寸和定位的属性,为了保证拿到的是精确值,不得不提前触发一次重排。
更详细的可以阅读 精读《web reflow》 这篇文章。
当然也不是每次访问元素位置都会触发
reflow
,在浏览器触发reflow
后,所有已有元素位置都会记录快照,只要不再触发位置等变化,第二次开始访问位置就不会触发reflow
。
精读《web reflow》
🎨 关于重绘的部分
关于重绘我认为其实就是影响布局的样式修改的元素外观更新,都可以认为是重绘。但是有部分会影响到元素位置/宽高的变更、显示/隐藏的CSS属性并不会触发重排。比如说:
- 使用
transform
属性使元素平移、形变等变换; - 使用
visible
和opacity
属性显示/隐藏元素;
甚至有一部分的属性可以使直接跳过重排重绘的步骤,直接进入合成(Composite
)阶段,还有关于重排重绘的优化我就不过多赘述了,感兴趣可以直接查看 《你真的了解回流和重绘吗》 这篇文章。
🧐 一些疑问
使用 absolute
或 fixed
脱离文档流后,修改元素定位等原来会触发重排属性还会触发重排吗?
会,但是因为不会影响父级和兄弟元素的定位,所以它的重排会非常的快。但是使用 float
来脱离文档流还使其它元素内的文本进行环绕,所以可能会发生大规模重排。具体可以参看这篇问答 修改浮动元素宽高之后是否会触发重排?
相关文档
Rendering: repaint, reflow/relayout, restyle / Stoyan’s phpied.com
weekly/242.精读《web reflow》 · ascoders/weekly
weekly/221.精读《深入了解现代浏览器三》 · ascoders/weekly
渲染流水线:CSS如何影响首次加载时的白屏时间?| 浏览器工作原理与实践
分层和合成机制:为什么CSS动画比JavaScript高效?| 浏览器工作原理与实践
HTML回流与重绘_ 空城机
介绍回流与重绘(Reflow & Repaint),以及如何进行优化? - 知乎
你真的了解回流和重绘吗 - 掘金
既不要重排也不要重绘,合成:transform如何实现动画效果? - 掘金