【问题标题】:Angular performance - pipe vs getter角性能 - 管道与吸气剂
【发布时间】:2017-09-19 00:06:26
【问题描述】:

例如,我有一个包含 ToDo 项目的简单数组。

[
  { name: 'Item 1', completed: false },
  { name: 'Item 2', completed: false }
  { name: 'Item 3', completed: true }
  { name: 'Item 4', completed: false }
]

此数组应显示为 2 行:
DoneNot Done

我有 2 个选择。
1 个 Getter。

public get doneItems() { 
    // filter and return only done items. And similar method for not done 
}

2 个管道。

问题:
您是否有一些指标或建议哪些选项具有更好的性能,以防应该有实时更新的数组(添加、删除、更新)和更复杂的项目以及页面上最多 100 个项目。
谢谢!

【问题讨论】:

  • 性能方面我无法想象有任何显着差异,如果您不解决网络上的关键任务问题!我会根据上下文和我想解决问题的方式来决定。
  • 只是做过滤,我认为 100 个项目没有任何区别。通常,更简单的解决方案是 - 更好
  • 知道了,谢谢!
  • 一般来说,不要使用管道进行过滤(angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe)。原因是每次更改检测启动并更新视图时管道都会运行,而组件中的代码则在您的控制之下。但是,在您的情况下,没有什么不同,因为您计划在每次模板更新中调用 getter。但我还是更喜欢把过滤器放在那里,因为将来重构代码会容易得多。

标签: javascript angular


【解决方案1】:

正如@mok 所强调的那样,在你的情况下,这根本不重要,但如果准确地解决你的问题......好吧,让我们推测一下。

吸气剂。在变化检测周期中,它可以被调用数十亿次。如果您在其中实现过滤,那么每次您的 getter 都会返回包含相同对象集的 new array。这将导致在 ngFor 指令中进行恒定的 diff 重新计算,每次都具有相同的结果。同样,对于 100 个项目,这个开销根本不应该是可测量的(角度团队在优化这件事上做得非常棒!),但它仍然是一堆不必要的操作。不是最好的选择。

管道。要在这里获得一个好的解决方案,您需要做两件事:a)实现pure过滤管道; 2) 确保您的源数组是不可变的,即不能对此数组进行更新 - 数组上的每个操作(添加/删除/移动/更改项目)必须 生成新数组。这样,angular 将为您提供几乎可以拥有的最佳选择 - 除非您更改源数组或过滤值,否则 angular 将在更改检测周期期间根本不采取任何措施来更新视图。所以,这里可以有很好的解决方案,但它需要一些仔细和深思熟虑的编码。

这里还有另一种选择。您可以创建两个部分数组 - DoneArray 和 NotDoneArray (命名很愚蠢,我知道,您可以做得更好;)) - 并在您更改主数组时填充它们。有了它,您可以创建两个只会返回这些数组的哑 getter,并在模板中使用这些 getter。只要主数组未更改,这些数组将是不可变的,因此不会导致更改检测的额外开销。在这种情况下,您根本不需要特殊的管道,只需使用普通的 *ngFor 就可以了。这里的缺点是存储数据需要两倍的内存,但同样,只有 100 个项目......谁在乎呢? :)

PS。忘记了非常重要的事情 - 角度文档中也有 some explanations 强烈建议不要以这种方式使用管道。您也需要牢记这一点,并检查您的解决方案在缩小后是否有效。

【讨论】:

    猜你喜欢
    • 2018-04-05
    • 2021-10-19
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    相关资源
    最近更新 更多