浏览器重排和重绘机制浅解
面试**公司的时候,遇到了“简要描述浏览器回流和重绘的区别及对性能的影响,如何尽量避免对页面性能的影响”的笔试题。由于我面试之前根本没做任何准备,所以只是单纯的写了一下我的简单理解:页面回流是由于元素宽高、层级位置发生变化而引起的重新布局。页面重绘是由于页面元素背景颜色等不影响布局的样式发生变化所引起的重新渲染。页面回流和重绘都会导致页面重复渲染,影响页面渲染效率。通过使用position:absolute
布局可以有效减少页面回流。回家之后,觉得自己答的太简单了,有些细节点没答清楚。仔细阅读了网上大佬的文章,为了便于以后回顾复习,故总结成此文。
浏览器的渲染原理
欲理解重排和重绘,必先了解浏览器渲染页面的机制。先上宝图:
为了方便以后与别人沟通,特将中文翻译图也贴出来
看图说话:
- 解析HTML生成DOM树
- 解析CSS样式表生成CSSOM(css object modal)
- 将CSSOM信息附着到DOM树上以生成渲染树(render tree包含每个节点的视觉信息)
- 生成流式布局(layout),即将渲染树的所有节点进行平面合成
- 将布局绘制(paint)到屏幕上
浏览器渲染一个html文档大致要经历以上步骤,其中前3步都是比较迅速的,最后两步是比较耗时的。
“生成布局”(flow)和“绘制”(paint)合称为“渲染”(render)
重排和重绘
一个网页在显示的过程中,至少要经过一次渲染。用户在浏览过程中,还会不断重新渲染
重新渲染,就需要重新布局(reflow)或重新绘制(repaint)
重排和重绘对性能的影响
频繁的重排会影响页面的刷新率(fps),特别是一些很耗时的重新布局。
如何减小重排和重绘对性能的影响
- 样式读写操作分离
- 通过class或csstext批量修改样式
- 缓存需要通过重排才能得到的值
- 通过document fragment或者clone node修改元素样式
- 通过先设置
display:none
隐藏元素后再修改 - 以绝对定位(absolute)或固定定位(fix)布局改变元素位置
- 使用虚拟dom前端框架
- 通过window.requestAnimationFrame和window.requestIdleCallback这两个方法调节渲染频率
- transform、opacity、filters这些动画都会有css3硬件加速(GPU加速),并且不会引起回流和重绘
- 在需要隐藏元素的场景下,使用
visibility
代替display:none
- 避免使用table布局(table需要大量的rendertree布局时间计算)
- 尽可能在DOM树最末端修改元素的class,限制重排影响的范围,使其影响尽可能少的节点
- 避免使用CSS表达式,可能会引发重排
- 将频繁重排或者回流的节点设置为图层,图层能够限制限制该节点渲染的影响范围。
will-change
、iframe
、video
标签,浏览器会将其渲染为单独的图层
本文严重参考阮一峰老师的网页性能管理详解,因为总结的实在时简洁明了,适合时时回忆参考。希望各位,不喜勿喷。喷,我也拦不住。