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)
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 howOnPush
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 throughObservable
channel.@aminpaks … how so? This is the example what I meant: https://plnkr.co/edit/P0BCfz
Because of
OnPush
and changes invoked bysetInterval
… no@Input
changes … it is necessary to callmarkForCheck()
in thesetInterval
.