回流(Reflow) 和 重绘(Repaint)

回流(Reflow) 和 重绘(Repaint)

在 JavaScript 中,回流(Reflow) 和 重绘(Repaint) 是浏览器渲染引擎处理网页更新的两个关键过程,直接影响页面性能。以下是详细分析:

一、核心概念

重绘(Repaint)

当元素样式改变但不影响布局时(如颜色、背景色、可见性等),浏览器只需重新绘制受影响的部分。

不触发几何计算,性能开销相对较小。

回流(Reflow / Layout)

当元素的尺寸、位置、布局结构发生改变(如宽度、高度、字体大小、DOM 增删),浏览器需要重新计算整个或部分页面的几何属性,并更新渲染树。

触发后续重绘,性能开销大(可能涉及整个文档或大量节点)。

二、触发条件

常见回流操作

// 几何属性变更

elem.style.width = "100px";

elem.style.height = "100px";

// 位置相关

elem.style.margin = "10px";

elem.style.padding = "5px";

// 布局结构变化

document.body.appendChild(newElem);

parent.removeChild(elem);

// 内容变化(文本、图片尺寸)

elem.innerHTML = "New content";

imgElem.style.height = "200px"; // 图片加载后

// 窗口缩放

window.addEventListener("resize", callback);

// 读取布局属性(强制同步回流)

const width = elem.offsetWidth; // 触发回流以获取最新值

常见重绘操作

// 仅视觉样式变化

elem.style.color = "red";

elem.style.backgroundColor = "#fff";

elem.style.visibility = "hidden";

elem.style.outline = "1px solid blue";

三、性能影响

回流比重绘代价更高

回流可能导致整个渲染树重新计算,而重绘仅更新像素。

现代浏览器的优化

浏览器通过队列化批量处理回流(如多次修改后合并为一次回流)。

例外:当读取布局属性(如 offsetTop、getComputedStyle())时,浏览器会强制刷新队列执行回流,以保证返回最新值。

四、优化策略

1. 减少回流次数

// 坏实践:多次修改样式触发多次回流

elem.style.left = "10px";

elem.style.top = "20px";

// 好实践:合并修改(CSSText 或 class)

elem.style.cssText = "left: 10px; top: 20px;";

// 或

elem.className = "updated-position";

2. 使用 DocumentFragment 批量操作 DOM

const fragment = document.createDocumentFragment();

for (let i = 0; i < 100; i++) {

const li = document.createElement("li");

fragment.appendChild(li);

}

document.getElementById("list").appendChild(fragment); // 仅一次回流

3. 避免频繁读取布局属性

// 坏实践:读取属性触发强制回流

const width = elem.offsetWidth; // 触发回流

elem.style.width = width + 10 + "px"; // 再次回流

// 好实践:缓存布局属性

const width = elem.offsetWidth; // 只触发一次

requestAnimationFrame(() => {

elem.style.width = width + 10 + "px";

});

// requestAnimationFrame 将样式修改推迟到下一帧渲染前执行

// 此时浏览器已经完成了当前帧的所有布局计算

// 修改操作被添加到渲染队列,但不会立即触发回流

4. 提升为合成层(GPU 加速)

/* 使用 transform/opacity 避免回流 */

.animate {

transform: translateX(100px); /* 不触发回流 */

opacity: 0.5; /* 不触发回流 */

will-change: transform; /* 提示浏览器优化 */

}

5. 脱离文档流后修改

// 1. 隐藏元素(触发一次回流)

elem.style.display = "none";

// 2. 进行多次修改

updateStyles(elem);

// 3. 重新显示(再触发一次回流)

elem.style.display = "block";

五、调试工具

Chrome DevTools Performance 面板

记录操作过程,分析 "Layout"(回流)和 "Paint"(重绘)耗时。

Rendering 面板

开启 "Layout Shift Regions"(回流区域高亮为蓝色)。

开启 "Paint Flashing"(重绘区域高亮为绿色)。

六、总结

特性

回流(Reflow)

重绘(Repaint)

触发原因

布局/几何属性变化(尺寸、位置)

样式变化(颜色、背景等)

性能开销

高(重新计算布局)

中低(重新绘制像素)

关联性

回流必定触发重绘

重绘不一定触发回流

优化关键

减少布局属性读写、批量 DOM 操作

避免不必要的样式修改

核心原则:

减少强制同步布局(避免在修改样式后立即读取布局属性)。

利用 CSS 动画替代 JS 动画(优先使用 transform/opacity)。

批量操作 DOM(使用 DocumentFragment 或离线 DOM)。

通过理解回流与重绘机制,可显著提升页面渲染性能(尤其在复杂交互和动画场景中)。

相关推荐

《十二战纪》测试时间介绍
365bet足球官方开户网

《十二战纪》测试时间介绍

🗓️ 07-26 👁️ 4256
柳岩:那些年,曾相过的亲
365bet足球官方开户网

柳岩:那些年,曾相过的亲

🗓️ 07-31 👁️ 4675
手机棋牌游戏怎么代理
365体育app网址

手机棋牌游戏怎么代理

🗓️ 09-01 👁️ 9726

友情链接