- Published on
重排重绘
- Authors

- Name
- Li WenKang
- https://x.com/liwenkang_space
浏览器的重绘重排,指的是当 DOM 和 CSSOM 被修改后,可能会重新触发浏览器渲染的关键路径布局和绘制。
- 重排:当 DOM 元素的变化影响了它的几何属性(大小,位置,布局),浏览器需要重新计算元素的几何属性,并重新构建文档树的全部或部分过程
- 重绘:当 DOM 元素属性的变化不影响它在文档流中的位置和大小时,浏览器需要重新绘制元素外观。 重排必定导致重绘,因为布局变化后需要重新绘制。而重绘不一定导致重排,因为布局可能未发生变化
什么情况下会触发重排?
- 可见 DOM 元素的增删
- 元素素位置、尺寸变化(宽度、高度、边距、填充、边框等)
- 元素内容变化(文本变化,图片变化)
- 浏览器可视窗口变化
- 计算某些布局信息(如offsetTop、getComputedStyle等方法)
什么情况下会触发重绘? 修改了 DOM 元素的外观属性,比如颜色,透明度,阴影,边框样式
重排重绘会导致什么问题?
- 消耗资源,造成卡顿
- 影响页面交互的流畅度,如果JavaScript执行、重排、重绘的时间总和超过16.67毫秒(60fps 屏幕),就会导致帧率下降,动画和滚动等交互效果会变得不流畅。
有哪些手段可以避免重排重绘?(最佳实践)
- 尽量避免在重排重绘后,立即读取一些布局属性,此时会打断浏览器本身的批量处理优化,强制同步布局,立即进行重排,造成强制同步布局
- 在修改 DOM 时,进行批量的写入和读取(比如先通过虚拟 DOM 做对比,计算出真实 DOM 需要更新的最小集合,再执行真实的 DOM 操作
- 在写入样式时,一次性完整写入,且做到读写分离
- 避免对样式的频繁操作
- 利用特殊的样式属性,比如 transform,opacity,使用合成层更新,开启 GPU 加速。使用 will-change 属性(仅针对复杂动画),提示浏览器将要发生变化。
- 使用变量对布局信息进行缓存,避免频繁读取导致的重排
- 使动画元素脱离普通文档流(position:fixed,absolute),避免影响其他元素的布局
- 避免 table 布局,只要有一个单元格改动,就会造成整个表格重排
- 对于复杂操作,可先将元素display设为none,操作完成后再显示,这样只在隐藏和显示时触发两次重排