外观
回流和重绘有什么差别?
回流(重排)是重新计算几何位置。重绘是几何不变、只重新画像素,例如改颜色。回流通常会带着重绘。只改 transform 和 opacity,往往合成一下就够了,不必重排。
原理
这些操作会让布局失效:读尺寸之前改过宽度、字号、内容、显示隐藏,或者窗口大小变了。浏览器会攒着,等到需要用布局结果时再算。
强制同步布局是在同一段脚本里先写样式、再读 offsetWidth 一类的值,浏览器只好立刻算。循环里对每个元素都这样读一次,就会反复布局。先把读放在一起,再把写放在一起。
display: none 会去掉盒子,引起布局。visibility 和 opacity 不是同一类成本。position 变化、字体加载后文字宽度变化,也会回流。
减少范围:让独立动画的元素留在自己的图层;大列表不要一次改上千个会触发布局的样式;用 contain 或 content-visibility 限制计算范围时,要检查滚动条和可访问性。
追问
怎么确认是布局导致的卡顿?
性能面板里看 Layout 和 Recalculate Style 的耗时,以及长任务。不要靠「改成 transform 一定更快」的印象。见 渲染优化。
transform 就完全没有成本吗?
它通常不触发布局,但图层会占内存,过大的图层和过多的重叠仍然贵。动画结束就不要一直 will-change: transform。
易错点
- 把所有样式修改都叫回流。改颜色一般只是重绘。
- 在滚动监听里读
getBoundingClientRect再写style,每帧都强制布局。 - 批量 DOM 插入时一条一条插进文档,每次都可能布局。先放进文档片段再挂一次。