简体   繁体   English

Angular2:如何触发变更检测?

[英]Angular2: How are change detection triggered?

I am currently trying to debug my application performance.我目前正在尝试调试我的应用程序性能。 It turns out that many frames take more than 200ms, and most of the time is spent in NumberFormat.format(), due to the various number pipes used.事实证明,由于使用了各种数字管道,许多帧花费的时间超过 200 毫秒,并且大部分时间都花在 NumberFormat.format() 上。 In the developers tools timeline, I see that change detection is triggered more often than required.在开发人员工具时间线中,我看到更改检测的触发频率高于所需。

For a single XHR ready state change of a single request, Lifecycle.tick() is called 11 times.对于单个请求的单个 XHR 就绪状态更改,Lifecycle.tick() 被调用 11 次。 I expected this to happen only once I assign the final result to a local field used in the template.我预计只有在将最终结果分配给模板中使用的本地字段时才会发生这种情况。 Even though the template bindings are not modified, running NumberFormat.format() on each records 11 times in a frame causes a noticable lag in the app.即使未修改模板绑定,在一帧中对每条记录运行 NumberFormat.format() 11 次也会导致应用程序出现明显延迟。

This is the Promise chain used in my code once the XHR ready state changes, in this case a search request:这是 XHR 就绪状态更改后在我的代码中使用的 Promise 链,在本例中为搜索请求:

  • The Promise wrapping the request resolves the response包装请求的 Promise 解析响应
  • An array is constructed by parsing the response JSON通过解析响应JSON构造一个数组
  • For each item in the array, a local model (ItemModel) is constructed:对于数组中的每一项,都会构造一个本地模型(ItemModel):
    • For each reference to other entities, the entity is fetched from the cache or, if absent, from the remote server;对于每个对其他实体的引用,该实体从缓存中获取,如果不存在,则从远程服务器获取; then converted to a local model instance.然后转换为本地模型实例。 Once all references are fetched, the Promise resolves the ItemModel instance.获取所有引用后,Promise 将解析 ItemModel 实例。 Note that this may cause several new Promise to be created, as several levels of references need to be resolved.请注意,这可能会导致创建多个新的 Promise,因为需要解析多个级别的引用。 Usually, entities are in the cache and these Promises resolve directly.通常,实体在缓存中,这些 Promise 会直接解析。
  • The result, an array of ItemModel, is assigned to a field in the controller.结果,一个 ItemModel 数组,被分配给控制器中的一个字段。

This sequence runs pretty fast.这个序列运行得非常快。 However, as seen in the timeline, Lifecycle.tick() is called each time after a local model instance is created.但是,如时间线所示,每次创建本地模型实例后都会调用 Lifecycle.tick()。 So if 10 references need to be resolved to build the complete local model tree, Lifecycle.tick() will be called 10 times.因此,如果需要解析 10 个引用来构建完整的本地模型树,Lifecycle.tick() 将被调用 10 次。 Why?为什么?

It also seems that sometimes Zone.fork is called when I create a local model.似乎有时在我创建本地模型时会调用 Zone.fork。 Why and why not always?为什么,为什么不总是?

I'd be happy to hear more on how zones and change detection are triggered in order to improve my app performances.我很高兴听到更多关于如何触发区域和更改检测以提高我的应用程序性能的信息。

Developer tools profile, timeline and network samples can be found here (expire on Oct 11 2015) Application code can be found here .可以在此处找到开发人员工具配置文件、时间线和网络示例(2015 年 10 月 11 日到期)可以在此处找到应用程序代码。

I finally got around this by using immutables collections from immutable-js and changing the changeDetection strategy to ChangeDetectionStrategy.OnPush .我终于通过使用不可改变的js immutables收藏和改变changeDetection战略,围绕这让ChangeDetectionStrategy.OnPush

For informations about change detection in angular2: http://victorsavkin.com/post/114168430846/two-phases-of-angular-2-applications有关 angular2 中变化检测的信息: http ://victorsavkin.com/post/114168430846/two-phases-of-angular-2-applications

This blog contains other useful resources.该博客包含其他有用的资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM