angular: Binding to a large array makes change detection very slow

I’m submitting a…

[x] Bug report  
[x] Feature request

Current behavior

Passing arrays with more than one million elements as an @Input binding makes the whole change detection mechanism very slow.

Expected behavior

Either change detection should work flawlessly, or if the process costs too much there must be an option to specify how to check the changes, maybe we can turn off detection in this case and not detect any changes for that specific input after it’s set.

Minimal reproduction of the problem with instructions

Open this example and observe. Note that Small List button will set 1000 elements to the Array and the performance will become 10 times faster.

What is the motivation / use case for changing the behavior?

In large applications there are cases that developer needs to be in charge of controlling every single part of the application. Even though Angular ships with lots of good features and it’s a great framework, sometimes the closed mechanism of doing things in its ecosystem makes it difficult to scale.

I hope you understand the motivation.

Thanks in advance.

Environment

Angular version: 4.3.3

Browser: All 

For Tooling issues:
- Node version: 7.10.0  
- Platform:  macOS Sierra

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 34 (15 by maintainers)

Most upvoted comments

what happens if developer is working with big lists in DEV mode then?

A smart developer will work with a small list. If the dev has to handle a lot of data it will google “pagination” or “virtual/infinite scroll”

I’m actually building a virtual scroll that I ended up facing this problem!!!

@mlc-mlapis I totally understand what you’re doing, but this is not the answer I’d accept. Angular is a very good framework, and I’d like to work with Observable instead. But your example makes things complicated and it’s not practical even though it’s how OnPush works.

Thanks for your time.

@mlc-mlapis You changed the type of @Input. Sorry but your example is not practical, it’s a workaround!

@aminpaks … and it is also true that objects are mutable also as default behaviour. So there should be some other reasons why arrays are not taken by the same way as objects.

@aminpaks … in your original code you pass a big array through @Input. Because you also use global (default) ChangeDetection = the whole app is checked then even the primitive big array is checked for a change. It’s evident that there is a difference between checking a big and a small array. So what do you expect?

Just the right concept is to eliminate the checking of the big array on each CD cycle. And this is what OnPush is doing. And yes, similar way is also through Observable channel.

@aminpaks … how so? This is the example what I meant: https://plnkr.co/edit/P0BCfz

Because of OnPush and changes invoked by setInterval … no @Input changes … it is necessary to call markForCheck() in the setInterval.