回流,也叫布局(Layout),指的是浏览器重新计算页面元素的位置和几何属性的过程。当页面的结构、内容或大小发生变化时,浏览器需要重新计算元素的位置和尺寸,以确保页面的正确显示。回流是一个高耗时的操作,因为它会影响整个页面或页面的大部分内容。
触发回流的场景:
width
、height
、padding
、margin
、border
等。position
属性)。getComputedStyle
或offsetHeight
等会强制浏览器计算样式的属性或方法。重绘指的是当元素的外观改变但不影响布局时,浏览器重新绘制这些元素。重绘不涉及重新计算元素的位置和尺寸,因此相对来说开销较小。
触发重绘的场景:
color
、background-color
等。opacity
。outline
属性。由于回流和重绘会影响页面性能,以下是一些减少回流和重绘的方法:
合并多次操作:例如一次性改变样式,而不是逐一改变。
// 不推荐
element.style.width = '100px';
element.style.height = '100px';
// 推荐
element.style.cssText = 'width: 100px; height: 100px;';
使用类:通过添加或移除类来改变样式,而不是直接修改样式属性。
.hidden {
display: none;
}
element.classList.add('hidden');
脱离文档流:在操作DOM之前,先将元素脱离文档流,操作完成后再插入。
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const div = document.createElement('div');
fragment.appendChild(div);
}
document.body.appendChild(fragment);
避免逐项查询DOM属性:例如不要在循环中查询DOM属性,先缓存值再使用。
const width = element.offsetWidth;
for (let i = 0; i < 100; i++) {
// 使用缓存的width,而不是每次都查询element.offsetWidth
console.log(width);
}
使用CSS3硬件加速:例如使用transform
和opacity
,这些属性通常不会触发回流。
.move {
transform: translateX(50px);
opacity: 0.5;
}