React点击事件后交互时间很高该怎么优化?
我正在做一个待办事项列表,点击按钮会动态渲染1000条数据。发现每次点击后交互时间(Time to Interactive)显示有2-3秒延迟,页面明显卡顿。我用了PureComponent和shouldComponentUpdate,但效果不明显。
代码结构大概是这样的:
class TodoList extends React.PureComponent {
state = { items: [] };
handleClick = () => {
const newItems = Array.from({length: 1000}, (_, i) => `Item ${i}`);
this.setState({ items: newItems });
};
render() {
return (
<>
<button onClick={this.handleClick}>加载数据</button>
<ul>
{this.state.items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</>
);
}
}
测试发现列表渲染时内存占用飙升,但状态更新逻辑应该没问题啊。是不是key设置有问题?或者有其他优化点没考虑到?
PureComponent和shouldComponentUpdate,但这里还有几个优化点可以试试。### 1. **key 的问题**
你的
key是用索引index设置的,这在动态列表场景下是不推荐的。React 官方文档里明确提到,如果列表项顺序会变或者有增删操作,用索引会导致不必要的重渲染。你可以把每条数据的唯一标识作为key,比如这样:然后在渲染时用
id作为key:这样更清晰,也避免了索引带来的性能问题。
---
### 2. **虚拟化列表**
渲染 1000 条数据对浏览器来说负担确实有点大。即使用户看不到那么多内容,React 还是会尝试渲染所有的 DOM 节点,导致内存占用飙升和卡顿。建议你用虚拟化列表(virtualized list),只渲染当前视口内的数据。
可以用现成的库,比如
react-window或者react-virtualized。简单举个例子,用react-window的话:这样就只渲染视口内的数据,滚动时动态更新,性能提升非常明显。
---
### 3. **setState 的批量处理**
虽然这里看起来不是主要问题,但还是提一下:
setState是异步的,如果需要频繁更新状态,可以考虑合并多次调用,减少渲染次数。不过你这个例子中一次更新 1000 条数据,应该没问题。---
总结一下,
key改为唯一标识,加上虚拟化列表,性能基本就能搞定。别看虚拟化简单,渲染大量数据的时候真香。希望这些改动对你有帮助!