Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: angular change detection gets triggered several times during element creation #18020

Closed
ippeiukai opened this issue Apr 12, 2019 · 11 comments
Labels

Comments

@ippeiukai
Copy link

Bug Report

Ionic version:

[x] 4.x

Current behavior:

Having many Ionic 4 components on a page slows down the initial display significantly. Having investigated the performance profile, it was found that custom element callbacks such as attributeChangedCallback were triggered many many times and Angular's change detection (NgZone#onMicrotaskEmpty -> ApplicationRef#tick) gets triggered every time.

Expected behavior:

Unnecessary change detection should not run while each Ionic component's element are created.

Steps to reproduce:

  • Ionic 4.2.0
  • Angular 7.2.11
  • zone.js 0.8.29

Opening (i.e. navigating to) a page with many many Ionic components while taking profile on Chrome Inspector's Performance tab. Searching for 'detectChanges' will tell you a large number of change detection has run.

Related code:

Having following line in zone-flags.ts, which is imported in polyfills.ts just before zone.js is imported, resolves the issue.

(window as any).__Zone_disable_customElements = true;

Alternatively downgrading zone.js to 0.8.26 should have the same effect as zone.js only patches customElement v1 since 0.8.27 (see angular/zone.js#1133).

Other information:

I have given a quick search over existing issues:

Ionic info:

Ionic:

   ionic (Ionic CLI)             : 4.12.0
   Ionic Framework               : @ionic/angular 4.2.0
   @angular-devkit/build-angular : 0.13.6
   @angular-devkit/schematics    : 7.3.6
   @angular/cli                  : 7.3.6
   @ionic/angular-toolkit        : 1.4.1

Cordova:

   cordova (Cordova CLI) : 8.0.0
   Cordova Platforms     : android 7.1.4, browser 6.0.0, ios 5.0.0
   Cordova Plugins       : cordova-plugin-ionic 4.1.7, cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.4.1, (and 21 other plugins)

System:

   Android SDK Tools : 26.0.2 (/■■■■■/Android/sdk)
   ios-deploy        : 1.9.2
   ios-sim           : 7.0.0
   NodeJS            : v8.9.1 (/■■■■■/node/v8.9.1/bin/node)
   npm               : 6.8.0
   OS                : macOS Mojave
   Xcode             : Xcode 10.1 Build version 10B61
@ionitron-bot ionitron-bot bot added the triage label Apr 12, 2019
@liamdebeasi
Copy link
Contributor

Hi there,

Thanks for the issue. We do not maintain development of zone.js. If you are running into an issue with zone.js, you can submit an issue on the zone.js GitHub.

I am going to close this as this is not an Ionic issue. The changes made in zone.js affect Web Components in general, not just Ionic components.

Thanks for using Ionic!

@ippeiukai
Copy link
Author

ippeiukai commented Apr 12, 2019

Hmm. I’m not sure if this issue belongs to zone.js. zone.js is a vital part of angular ecosystem and @ionic/angular is supposed to work well with it.

In fact, @ionic/angular deliberately initialises Ionic inside the angular zone excluding certain things. As such, it seems to me like this has more to do with how @ionic/angular integrates itself into Angular than how zone.js interacts with web components in general.
https://github.com/ionic-team/ionic/blob/v4.2.0/angular/src/app-initialize.ts

@liamdebeasi
Copy link
Contributor

Hi there,

Thanks for the follow up. Can you provide an example repository where your app is slow as a result of having this zone.js change?

Thanks!

@ippeiukai
Copy link
Author

@liamdebeasi I’ll give it a try over the weekend. When I experimented it, it reproduced even with 100 ion-items in a list; shouldn’t be too hard to make a sample app to publish.

ippeiukai added a commit to ippeiukai/ionic-issue18020 that referenced this issue Apr 15, 2019
ippeiukai added a commit to ippeiukai/ionic-issue18020 that referenced this issue Apr 15, 2019
@JiaLiPassion
Copy link

@ippeiukai, @liamdebeasi, just like @ippeiukai said, zone.js patched all APIs of CustomElements from 0.8.27, and will cause additional change detection.
And because now all ionic component is WebComponent, so this issue occured.

I checked the source of ionic/stencil,
For example, https://github.com/ionic-team/stencil/blob/647a47d34631e3f5a7a5335cc7cacd0a75ba71b6/src/core/attribute-changed.ts
stencil basically will register such kind of callback to handle such as attribute/property mapping handlings.

So if those callbacks(connected/attributeChangedCallback/etc... which are registered by stencil or ionic, will not be invoked from outside of Angular, for example from some vanilla js on the same page. We can just disable zone.js patching Custom Elements. And if this is the common case in ionic, maybe we can deploy this zone-flag.ts with (window as any).__Zone_disable_customElements = true; inside with ionic together.

@liamdebeasi
Copy link
Contributor

Hi @ippeiukai,

What @JiaLiPassion said sums things up pretty well. On the Ionic side, we are going to look into a way we can automatically include (window as any).__Zone_disable_customElements = true; for all Ionic/Angular users. While I don't think this is an Ionic bug, I do agree that the net result is undesirable in the situation you presented.

Thanks for bringing this to our attention! I'll post again here when I have an update. 🙂

@liamdebeasi
Copy link
Contributor

Hi @ippeiukai,

I updated the Ionic starters to include this flag by default. Additionally, we will update the documentation to provide instructions for developers who already have Ionic apps/create Ionic apps outside of the CLI.

Thanks!

@LuizTokuhara
Copy link

Hi @liamdebeasi ,
Could you please provide the doc link for this fix.

@liamdebeasi
Copy link
Contributor

The docs should be deployed soon, but here is the source that you can read: ionic-team/ionic-docs#651

@ionitron-bot
Copy link

ionitron-bot bot commented May 26, 2019

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators May 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants