JS 浏览器 重排 reflow 重绘 repaint
什么是重排和重绘
重排和重绘 是浏览器渲染的常见过程重排是指当HTML元素的位置、大小等发生变化的时候,浏览器需要重新计算它的位置、以及受它影响的所有元素的位置,
这个重新计算的过程,我们称之为 重排
重绘是指当HTML元素发生任何变化的时候,浏览器窗口的内容需要重新绘制新内容,这个重新绘制的过程我们称之为重绘
从此可以看出当HTML元素发生任意变化的时候,都有可能触发浏览器重排和重绘
重排和重绘有什么问题呢?
浏览器重排和重绘是非常耗时的过程,也就是说是非常影响性能的一个瓶颈点
其中会涉及到大量的计算过程、图像绘制过程等
我们来看下重排和重绘的过程
我们来看下如下一张图
这张图描绘了浏览器的渲染过程
HTML 经过HTML解析之后,生成DOM树
CSS规则 经过CSS解析之后,生成规则树
DOM树和规则树进行合并处理,生成渲染树
渲染树经过GUI处理后直接渲染在浏览器窗口
重排就是重新生成渲染树的过程 Render Tree
重绘就是把渲染树Render Tree重新绘制到浏览器窗口的过程 Display
相比而言,重排有更大的计算量,比重绘更耗性能,实际线上产品,重绘是不可避免的,但是重排可以进来减少次数
哪些变化会引起重排1、HTML第一次加载渲染的时候,第一次生成渲染树,所有元素都需要计算一次
2、通过拉伸导致浏览器窗口大小发生变化 (如果仅仅是浏览器位置变化,不会重排)
3、HTML元素的显示和隐藏的变化过程
4、HTML内容变多或变少的变化过程,因为内容长度变化导致了HTML元素的大小变
5、等等其他HTML变化过程
总之,只要影响了HTML元素的大小、位置、显示隐藏状态等,都会触发重排
哪些变化会引起重绘
所有HTML变化导致重排的过程,一定会引起重绘,因为需要重新绘制到浏览器
但是重绘不一定会触发重排
比如HTML元素的各种颜色变化、visibility的显示与隐藏,会引起重绘,但是不会引起重排
如何在重排和重绘方面提升性能呢?重排和重绘不可避免,但是我们可以尽量减少重排和重绘的次数
首先
我们也知道现代浏览器中对于重排和重绘有一些优化手段,并不会每次发生重排就立即执行,而是
极短时间内的重排操作会缓冲然后合并执行
其次
我们在开发代码的时候,应该有意识到发生重排和重绘的时机
如一般的代码:1
2
3el.style.left = '10px';
el.style.top = '20px';
el.style.fontSize = '30px';
这里有三次对HTML元素的修改,每次都会触发重排(影响了元素的大小和位置)
优化后的代码:1el.style.cssText += ';left:10px;top:20px;font-size:30px;';
合并对HTML元素的修改,只触发一次重排和重绘当然第一种写法,游览器也会有一定的优化合并操作的