本文主要介绍如何减少重绘与重排,来提高 JavaScript 在浏览器中的执行效率。
什么是重绘与重排?
在了解如何优化JavaScript代码来提高性能之前,让我们先了解一下重绘和重排的概念:
重绘是什么:重新绘制。当 DOM 元素样式的改变影响了元素的可见性、但没有改变它在文档流中的位置时,浏览器会重新绘制该元素,以便反映样式的变化。重绘通常是影响性能的一种情况,因为它会引起不必要的图形重新绘制。
重排是什么:重新生成布局。当DOM 的变化影响了元素的几何属性(宽和高)--比如改变边框宽度或给段落增加文字导致行数增加--浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。
重排与重绘的关系
重排一定会导致重绘,重绘不一定导致重排。如果DOM变化不影响几何属性,元素的布局没有改变,则只发生一次重绘(不需要重排)。
导致重绘与回流的常见操作
以下是一些常见导致重绘与回流的操作:
- DOM 操作:频繁地对 DOM 进行增删改查操作。
- 样式操作:修改元素的样式,特别是通过操作
style
属性。 - 布局属性读取:读取元素的尺寸或位置信息,如
offsetTop
、offsetLeft
、clientWidth
、clientHeight
等。 - 获取布局信息:获取布局相关的属性,如
scrollTop
和scrollLeft
。 - 修改布局属性:修改元素的尺寸或位置,如改变元素的宽度、高度、内外边距等。
- 窗口大小变化:当浏览器窗口大小改变时,会导致整个页面的回流。
对性能的影响
重排和重绘会不断触发,这是不可避免的。但是,它们非常耗费资源,是导致网页性能低下的根本原因。
提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。
优化策略
1. 尽量不要把读操作和写操作,放在一个语句里面。
// 错误示例
div.style.left = div.offsetLeft + 10 + "px";
div.style.top = div.offsetTop + 10 + "px";
// 优化后
var left = div.offsetLeft;
var top = div.offsetTop;
div.style.left = left + 10 + "px";
div.style.top = top + 10 + "px";
2. 使用 class
进行样式修改
通过添加或移除 class
来修改样式,而不是直接操作 style
属性。这样会减少重绘次数。
// 错误示例
for (let i = 0; i < 1000; i++) {
element.style.color = 'red';
}
// 优化后
for (let i = 0; i < 1000; i++) {
element.classList.add('highlight');
}
3.批量 DOM 操作
频繁地对 DOM 进行增删改查会导致多次重绘和重排。相反,你可以将多个 DOM 操作合并成一个批量操作。
4. 缓存布局属性读取结果
避免在循环中多次读取布局属性,可以先将其存储在变量中。
// 错误示例
for (let i = 0; i < elements.length; i++) {
const top = elements[i].offsetTop;
// 使用 top 做一些操作...
}
// 优化后
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
const top = element.offsetTop;
}
5. 使用 requestAnimationFrame
对于需要进行大量计算或动画的操作,使用 requestAnimationFrame
来执行,这样可以优化动画性能,并在一帧中完成所有重绘与重排操作。
最后如果本篇文章有错误或问题,欢迎指正,谢谢!!!
参考文章
[如何优化 JavaScript 性能:减少重绘与回流]