ReactJs+Redux拖拽提案编辑器新增大量内容后运行卡顿问题求解
性能优化解决方案
根因定位
你遇到的卡顿并非遍历数组本身导致,核心是Redux单状态未做变更隔离、React全量重渲染两大问题:单reducer下任意小的状态变更都会触发所有依赖该状态的组件重渲染,当页面元素多了之后,每秒几十次的重渲染会直接占满主线程,表现为操作卡顿。
落地优化方案
- 状态读写粒度拆分
使用useSelector时仅取组件实际依赖的状态片段,不要直接取整个pages数组。例如元素组件仅取对应元素的配置数据,页面组件仅取当前页的配置,避免单个元素修改触发全量组件更新。 - 组件渲染拦截
所有页面、行、列、元素组件均用React.memo包裹,对于引用类型的props,要么传递唯一ID作为props、组件内部再根据ID取对应配置,要么在memo的第二个参数中添加精准的比较逻辑,仅当组件依赖的数据实际变更时才触发重渲染。 - 非可见区域懒渲染
采用虚拟滚动方案,仅渲染视口内可见的1-2页内容,其余页面用固定高度的占位符替代,滚动到对应区域时再渲染实际内容,从根源上减少需要遍历渲染的节点数量。 - Redux更新逻辑优化
拆分单reducer为提案信息、页面内容、全局样式三个独立reducer,修改单个元素配置时,仅更新pages数组中对应节点的内容,不要全量替换整个pages数组,保证未修改节点的引用稳定,不会触发不必要的更新。 - 操作过程节流
拖拽、修改样式等高频操作过程中,不要实时同步更新Redux状态,仅更新当前操作元素的DOM,操作结束后再将最终结果同步到Redux,减少状态更新的频次。
额外建议
如果后续还要扩展表格、表单等复杂组件,可以给每个组件单独设置缓存,渲染前先比对当前组件的配置和上一次渲染的配置是否一致,一致的话直接复用之前的渲染结果,进一步降低渲染压力。
内容的提问来源于stack exchange,提问作者Pulkit Khullar
相关产品推荐
相关产品推荐

