Performance issues because of _ngZone.onStable.subscribe
See original GitHub issueBug description:
There are a few components in this library with a line
_ngZone.onStable.subscribe(() => this._updatePopupPosition());
in the constructor (dropdown, tooltip, popover, typeahead, datepicker).
_ngZone.onStable
is fired when the microtask queue is empty and Angular does not plan to enqueue any more. In my application, this happens too many times and too frequent and leads to freezes in Safari and Firefox.
Let’s think about a more sophisticated approach to reposition a popup in order to optimise performance.
The minimal example to reproduce the issue
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="dropdown" ngbDropdown>
<a class="dropdown-toggle" ngbDropdownToggle>111</a>
<div ngbDropdownMenu>
<div>111</div>
<div>222</div>
<div>333</div>
</div>
</div>
`,
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
ngOnInit(): void {
setInterval(() => {
console.log('interval');
}, 100);
}
}
When you open the dropdown menu it starts doing repositioning every 100 ms.
Versions of Angular, ng-bootstrap and Bootstrap:
Angular: 7.2.15 ng-bootstrap: 4.1.3
Issue Analytics
- State:
- Created 4 years ago
- Reactions:3
- Comments:7 (4 by maintainers)
Top Results From Across the Web
Using Zones in Angular for better performance
In this article we'll take a look at how to use Zone APIs to improve our app's performance!
Read more >Boosting performance of Angular applications with manual ...
Angular to detect the changes puts a wrapper on Zone.js called NgZone to enable run updates when it detects an async operation event....
Read more >Do you still think that NgZone (zone.js) is required for change ...
Yes, Zone and NgZone is used to automatically trigger change detection as a result of async operations. But since change detection is a...
Read more >NgZone - Angular
The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that...
Read more >Implement custom dirty-checking using NgZone/Zone
No, that would be a huge performance issue. change detection mechanisms must find a way of comparing the previous state of a changed...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I found how the same thing is done in Angular Material https://github.com/angular/components/blob/master/src/cdk/overlay/overlay-ref.ts#L136 They use
take(1)
.Hello @cwayfinder,
As mentioned by @fbasso, have you tried instantiating this third-party library outside of the Angular zone?
More precisely, you should ensure than any intensive (frequent) processing is scheduled outside of the Angular zone (I don’t know the details of the API of this library):
runOutsideAngular
.If you ever need to react to some updates done by the library, use its API (plug into some events or whatever it is) to update your application data model, or anything, inside of the Angular zone again:
run
.It is true that our positioning is an expensive task, but there should not be so many change detection cycles triggered, this is a more general concern for any Angular application. EVERYTHING depending on change detection is recomputed every time. This includes other parts of our code but also your code.
The proposed solution of caching (#3214) is an idea of improvement, but proper caching needs proper cache invalidation, and in this case, to be properly done in a generic way, this would still require to calculate positions and sizes. #3214 makes some strong hypotheses to avoid doing so, but I would not be in favor of a restricted solution for an issue which could be circumvented more properly.