提升网页性能的秘密:在 Vue 和 React 中优化重绘与回流


在现代网页开发中,尤其是在使用 Vue 和 React 等前端框架时,性能优化依然是提升用户体验的关键。虽然这些框架通过虚拟 DOM 等技术简化了与 DOM 的交互,但重绘(Repaint)和回流(Reflow)的概念依然存在,并且仍然影响着性能。今天我就来重新巩固下这2个概念。

什么是重绘?

重绘是指当元素的外观发生变化(如颜色、背景),但不涉及布局的变化,浏览器需要重新渲染该元素。虽然重绘相对轻量,但频繁的重绘仍会影响应用性能,我们当然是希望越少越好。

什么是回流?

回流是指当元素的尺寸或几何属性发生变化时,浏览器需要重新计算并更新整个页面的布局。这一过程通常比重绘消耗更多资源,尤其是在复杂的应用中,所以我们要避免多余的回流。

为什么在框架中也需要关注重绘与回流?

即使在使用 Vue 和 React 等框架时,重绘与回流仍然存在。例如,当组件的状态变化导致重新渲染时,框架会触发 DOM 的更新,从而可能引发重绘或回流。因此,理解这些概念有助于我们写出更高性能的组件。

在 Vue 和 React 中的优化策略

1. 善用计算属性和 Memoization

在 Vue 和 React 中,通过计算属性computed或使用 useMemo 钩子,可以有效减少不必要的渲染和优化性能。

示例:Vue 计算属性

1
2
3
4
5
6
// 具有缓存性质,他只有当监听属性发生变化的时候,才会触发
computed: {
filteredItems() {
return this.items.filter(item => item.isActive);
}
}

示例:React useMemo

1
2
3
const filteredItems = useMemo(() => {
return items.filter(item => item.isActive);
}, [items]);
2. 合理使用 key

在列表渲染中,合理使用 key 属性可以帮助框架识别哪些元素需要更新,从而减少重绘和回流。

示例:

1
2
3
{items.map(item => (
<ListItem key={item.id} item={item} />
))}
3. 控制组件的更新

通过 shouldComponentUpdate(在类组件中)或 React.memo(在函数组件中),可以有效控制组件何时需要更新,从而避免不必要的重绘。

示例:React.memo

1
2
3
const MyComponent = React.memo(({ item }) => {
return <div>{item.name}</div>;
});
4. 使用事件节流和防抖

在处理频繁事件时,如窗口 resize 或滚动,使用节流和防抖技术可以减少频繁的重绘和回流。

示例:使用 lodash 的 debounce

1
2
3
4
5
6
7
8
const handleResize = debounce(() => {
console.log('窗口大小改变!');
}, 200);

useEffect(() => {
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
5. 按需加载

在大型应用中,按需加载组件可以显著提高初始渲染性能,并减少不必要的回流。React 提供了 React.lazySuspense 来实现这一功能。

示例:

1
2
3
4
5
const LazyComponent = React.lazy(() => import('./LazyComponent'));

<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
回流必定发生重绘,但是重绘不一样发生回流,回流的性能开销也比重绘大。

最后了解下引起回流重绘的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
常见引起重绘的属性
color
border-style
visibility
background
text-decoration
background-image
background-position
background-repeat
outline-color
outline
outline-style
border-radius
outline-width
box-shadow
background-size

常见引起回流的属性和方法
元素的尺寸发生改变
dom元素发生添加或删除
js修改dom的style属性
浏览器窗口resize事件发生
任何会改变元素几何信息(元素的位置和尺寸大小)的操作,都会触发重排

Ok,回流和重绘我们基本了解了。

我的微信公众号: 梨的前端小屋


  目录