编程 如何在前端避免重排(Reflow)和重绘(Repaint)

2024-11-19 02:28:18 +0800 CST views 520

如何在前端避免重排(Reflow)和重绘(Repaint)

重排(Reflow)和 重绘(Repaint)是浏览器在处理页面渲染时的两大性能开销,频繁的重排和重绘会导致页面响应变慢、卡顿,影响用户体验。因此,减少和避免重排和重绘是前端优化的关键。

1. 避免重排(Reflow)

重排发生在当页面布局变化时,例如修改元素的尺寸、位置或在 DOM 中新增、删除元素。这是最消耗性能的操作之一。

1.1. 减少DOM操作

DOM 操作是引发重排的主要原因之一。尽量减少频繁的 DOM 结构变化,使用批量操作技术来减少性能损耗。

  • 方法:使用 DocumentFragment 或者一次性更新 DOM,避免逐个操作 DOM。
let fragment = document.createDocumentFragment();
let div = document.createElement('div');
fragment.appendChild(div);
document.body.appendChild(fragment);

1.2. 避免使用特定属性

有些属性会强制触发重排,例如:

  • offsetWidth
  • offsetHeight
  • scrollTop
  • clientWidth

在读取这些属性时,浏览器会立即重新计算页面布局,导致性能下降。避免频繁读取这些属性,或者缓存它们的值。

1.3. 使用CSS动画而非JavaScript

尽量使用 CSS 动画过渡效果 来代替 JavaScript 的样式变化,因为 CSS3 动画利用硬件加速,可以避免频繁触发重排。

1.4. 利用 position: absoluteposition: fixed

对于不需要参与页面文档流的元素,使用 position: absoluteposition: fixed,减少其影响其他元素的重排。

1.5. 使用 display: none

隐藏元素时,使用 display: none,它不会占据空间,也不会导致重排;相比之下,visibility: hidden 仅隐藏元素,但它仍然占据空间,可能引发页面重排。

1.6. 使用 requestAnimationFrame

将多个 DOM 操作放在 requestAnimationFrame 中,使浏览器可以在下一帧之前批量处理所有变更,减少中间无效的重排。

requestAnimationFrame(() => {
  // 批量处理 DOM 操作
});

2. 避免重绘(Repaint)

重绘是当元素外观发生变化时(如颜色、背景图像变化)浏览器需要重新绘制的过程,虽然它比重排消耗小,但频繁的重绘也会影响性能。

2.1. 使用 will-change 属性

will-change 告诉浏览器即将发生变化的样式,提前做好优化准备,减少不必要的重绘。

.element {
  will-change: transform;
}

2.2. 使用合成层

通过使用 translateZ(0)translate3d(0, 0, 0) 等属性将元素移入 GPU 加速的合成层,这样能将它们从主文档流中分离出来,避免影响其他元素。

.element {
  transform: translateZ(0);
}

2.3. 使用离屏Canvas

对于复杂的图形操作,可以先在离屏 Canvas 中绘制,再将结果绘制到屏幕上,避免频繁的重绘。

2.4. 使用 display: contents

display: contents 可以使元素只作为 DOM 容器存在,而不会在渲染树中产生任何视觉边界,从而减少不必要的重绘。

2.5. 使用 CSS 变量

使用 CSS 变量 可以减少重绘开销,尤其是在需要频繁改变样式时。

2.6. 避免昂贵的样式属性

尽量避免使用如 clip-pathfiltermix-blend-mode 等性能开销大的属性,因为它们可能导致大量重绘。


3. 总结

为了避免重排和重绘,以下几条策略非常关键:

  • 批量操作 DOM,尽量减少 DOM 操作次数。
  • 使用合成层,将频繁变化的元素放到单独的合成层。
  • 使用 will-change 提前通知浏览器进行优化。
  • 减少使用昂贵的 CSS 属性,例如 filterclip-path

通过这些优化技术,可以显著提高页面性能和用户体验。
images

复制全文 生成海报 前端开发 性能优化 网页设计

推荐文章

windon安装beego框架记录
2024-11-19 09:55:33 +0800 CST
Nginx rewrite 的用法
2024-11-18 22:59:02 +0800 CST
快手小程序商城系统
2024-11-25 13:39:46 +0800 CST
imap_open绕过exec禁用的脚本
2024-11-17 05:01:58 +0800 CST
使用 Vue3 和 Axios 实现 CRUD 操作
2024-11-19 01:57:50 +0800 CST
全新 Nginx 在线管理平台
2024-11-19 04:18:33 +0800 CST
Vue3中如何处理WebSocket通信?
2024-11-19 09:50:58 +0800 CST
API 管理系统售卖系统
2024-11-19 08:54:18 +0800 CST
Vue3中的组件通信方式有哪些?
2024-11-17 04:17:57 +0800 CST
12个非常有用的JavaScript技巧
2024-11-19 05:36:14 +0800 CST
JavaScript中的常用浏览器API
2024-11-18 23:23:16 +0800 CST
JS 箭头函数
2024-11-17 19:09:58 +0800 CST
Vue3中如何处理路由和导航?
2024-11-18 16:56:14 +0800 CST
Go语言SQL操作实战
2024-11-18 19:30:51 +0800 CST
利用图片实现网站的加载速度
2024-11-18 12:29:31 +0800 CST
Roop是一款免费开源的AI换脸工具
2024-11-19 08:31:01 +0800 CST
FastAPI 入门指南
2024-11-19 08:51:54 +0800 CST
关于 `nohup` 和 `&` 的使用说明
2024-11-19 08:49:44 +0800 CST
程序员茄子在线接单