question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Performance issues because of _ngZone.onStable.subscribe

See original GitHub issue

Bug 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:open
  • Created 4 years ago
  • Reactions:3
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
cwayfindercommented, May 19, 2019

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).

0reactions
ymeinecommented, Jun 18, 2019

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found