浏览器的重绘与回流
更多个人博客:(https://github.com/zenglinan/blog)
如果对你有帮助,欢迎star。
之前的《理解浏览器对页面的渲染过程》 一文中提到 :
浏览器会处理 HTML CSS 标记, 生成 DOM CSSOM 树。
然后将 CSSOM DOM 树处理为 Render 渲染树, 根据渲染树来计算节点位置, 绘制节点。
但是我们可能会对元素节点的样式进行动态修改, 比如修改颜色、宽高、位置等。这些行为可能导致上述过程全部或部分重新执行, 俗称重绘与回流。
回流
回流一定重绘, 但重绘不一定回流。
当渲染树中全部或其中一部分元素发生尺寸、布局或隐藏显示等改变时, 浏览器重新渲染部分或全部文档的过程称为回流。
触发页面回流的因素
关键词: 影响布局 | 查询宽高、距离
一、CSS
- 盒子模型相关
width/height/padding/border/margin
- 节点文字相关
font/line-height/font-weight/
- 定位相关
postion/display/float/clear/
二、JS
- 增删 DOM 节点, 改变 DOM 节点的布局
- 计算元素的宽高、距离:
clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
width、height
getComputedStyle()
getBoundingClientRect()
重绘
当渲染树中一些元素需要更新属性时, 触发重绘, 这些属性只关系到元素的外观风格, 不会对布局产生影响。
触发重绘的属性
关键词: 不影响布局
比如: color, border-style, visibility, background, outline, box-shadow...
重绘回流的优化
CSS 方面
- 避免使用 table布局, 因为 table 布局需要多次计算元素宽度。
- 动画速度不要调的太快, 一些复杂的动画新建一个图层去实现。
- 避免使用CSS表达式, 如: calc 计算属性。
JS 方面
- 避免频繁操作样式, 最好用一个 className 一次操作完。
- 不要频繁读取元素宽高和距离等属性, 尽可能用变量缓存起来。
- 如果需要频繁操作 DOM 节点, 可以先设为
display: none
, 操作完后再设回去(将回流次数减到最少)。
番外: 如何在 Chrome 中查看页面重绘回流的情况?
感谢万能的 Chrome 调试器, 在 Performance 中可以查看页面的执行性能
<img width="329" alt="1" src="https://user-images.githubusercontent.com/37680843/63674012-26f6f580-c818-11e9-8006-02a9f44ef04e.png">