You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular+Ngrx场景下,处理10k条数据时直接返回原数组慢但返回副本快的原因是什么?

Angular+Ngrx场景下,处理10k条数据时直接返回原数组慢但返回副本快的原因是什么?

嘿,这个问题我之前做大型列表需求的时候也踩过类似的坑,当时还愣了半天——怎么返回原数组反而更慢?咱们来唠唠这背后的门道:

首先得对应上你的场景(虽然你贴的代码没写完,但结合需求猜个八九不离十):第一个版本是Selector直接把原数组citizensState.people扔给组件,第二个版本应该是在Selector里提前做了过滤(比如citizensState.people.filter(p => p.surname === '目标姓氏')),返回的是过滤后的新数组副本对吧?

为啥前者慢后者快?核心绕不开两个关键:Angular的变更检测逻辑和Ngrx Selector的记忆化特性:

  • 第一点,组件渲染的压力差:
    当你直接返回10k条的原数组时,组件模板里的*ngFor或者相关管道每次都要遍历这10k条数据去渲染、做对比。哪怕你最终只需要显示几百个符合条件的人,只要过滤逻辑是放在组件里做的,那每次变更检测周期都得把10k条全跑一遍,这个开销能不大吗?
    但如果把过滤逻辑移到Selector里,返回的是已经筛好的小数组(比如几百条),组件拿到手直接渲染就行,遍历量直接砍到原来的几十分之一,速度自然就上来了。

  • 第二点,Ngrx记忆化的“偷懒”机制:
    Ngrx的createSelector自带记忆化(Memoization)功能——简单说就是它会缓存上一次的输入参数和返回结果。如果你的Selector直接返回原数组,那只要上层的selectCitizensState返回的状态对象引用变了(哪怕只是状态里的某个无关属性比如loading切换了,people数组本身压根没动),这个Selector就会重新执行,返回同一个原数组引用。这时候如果组件用的是默认变更检测策略,Angular会傻乎乎地去对比数组里的每一项内容,确认有没有变化,10k条数据的全量对比,慢是必然的。
    而当你返回过滤后的新数组副本时,Selector的记忆化就发挥作用了:只有当people数组本身的引用变化,或者过滤条件相关的状态变了,Selector才会重新计算并返回新的数组引用。这时候如果组件用了OnPush变更检测(这也是Ngrx项目的最佳实践),只有当数组引用真的变化时才会触发重新渲染,不会做无意义的全量对比,性能自然就上去了。

还有个容易被忽略的细节:直接返回原数组时,组件里任何依赖这个数组的操作(比如自定义管道、计算属性),都会在每次变更检测时重新执行,10k条数据的重复计算叠加起来,卡顿感就特别明显。而返回过滤后的副本,这些操作的执行量直接变小,整体性能提升就非常显著。

备注:内容来源于stack exchange,提问作者DaccoTheTaco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 16:13:17