Ionic-framework: bug: Interface gets very slow when adding ion components (Github repo)

Created on 22 Nov 2020  路  8Comments  路  Source: ionic-team/ionic-framework

Bug Report

Ionic version:


[x] 5.5

Chrome: 85.0.4183.121

Current behavior:
When adding an ion component to my html it takes sometime to load

Expected behavior:
The components should not delay to appear

Steps to reproduce:
Just download the repository and use
npm install
ionic serve

the page will load and you will see a huge delay to load the login form, if you remove

          <ion-spinner name="bubbles" *ngIf="true"></ion-spinner>

the page will load normal, note that any ion component is causing the page to slowdown

Related code:

https://github.com/conde2/slowbug
Ionic:

   Ionic CLI                     : 6.12.1 (/usr/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 5.5.0
   @angular-devkit/build-angular : 0.1002.0
   @angular-devkit/schematics    : 10.2.0
   @angular/cli                  : 10.2.0
   @ionic/angular-toolkit        : 2.3.3

Capacitor:

   Capacitor CLI   : not installed
   @capacitor/core : not installed

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v14.12.0 (/usr/bin/node)
   npm    : 6.14.8
   OS     : Linux 5.8
triage

Most helpful comment

So the issue here is due to hydration of Ionic components. By default, your app has the following CSS:

html {
  visibility: hidden;
}

When your app is hydrated, the html element gets the hydrated class applied which gives the following CSS:

html.hydrated {
  visibility: visible;
}

All Ionic components inherit this visibility. So for example, if your app is not hydrated, ion-content will not show. As a result, your sign in form will not show up either.

The behavior your are seeing is due to the transition value that you pointed out earlier. The following CSS:

.signin-signup {
  transition: 1s 0.7s ease-in-out;
}

Gets computed as:

transition-duration: 1s;
transition-property: all;
transition-timing-function: ease-in-out;
transition-delay: 0.7s;

The key here is the transition-delay. When changing visibility: hidden to visibility: visible, the transition kicks in since it is applied to all properties. visibility does not "animate" in like opacity does, so the affected elements will just appear instead. Since you have a delay of 0.7s, the browser will wait 0.7s before showing the elements, resulting in the behavior you experienced.

To verify this, try changing 0.7s to 10s. You should notice that the sign in form takes even longer to show up now. Additionally, to verify that this is due to visibility changing, try adding visibility: visible to .signin-signup and you should notice that the form appears instantly.

The next mystery is why this happens when ion-spinner is present. My best guess is the inclusion of this component requires additional processing time that causes the visibility to change in two different frames, causing the transition to take effect. I have a minimal version of your app running and if I refresh several times, sometimes the issue happens and sometimes it does not. If the visibility is set to hidden and then set to visible in the same frame, the transition should not take effect.

While I do not think this is a bug in Ionic Framework, it certainly is pretty confusing. My recommendation is to be specific with what your transitions apply to as the default is to have the transitions apply to every property. So for transition: 1s 0.7s ease-in-out;, consider having it apply to specific properties such as opacity or transform instead.

I am going to close this issue out. Thanks!

All 8 comments

Thanks for the issue. Can you provide some steps to reproduce the issue?

slowslow

To reproduce, just need to install de packages and run ionic serve.
The login form should load without any delay. If you remove the ion component

      <ion-spinner name="bubbles" *ngIf="true"></ion-spinner>

everything works fine

Thanks for the clarification. From the gif you posted, the slow down you are referring to is the delay before the "Sign In" form is rendered, correct?

If so, I still get that slow down even after removing ion-spinner. Looking at the console, it looks like that "Sign In" form is rendered once a Firebase Authentication HTTP call returns. Can you try reproducing this issue in a blank Ionic starter app without Firebase?

Thats the result I get when removing the ion-spinner, the sign in form is not dependend on any HTTP request.

You can remove the canActivate guard to test, I forgot to remove it, but thats not the problem.

noslow

I just update the repo to remove all the http requests not coming from localhost, and removed everything that was not related to the bug. I think this will help you, note that the problem still happens.

You can pull the changes from the repository.

I just found that removing the transitions, then the form appears without delay, so there is something in the ion components that makes the transition to apply to the entire form.

Captura de tela de 2020-11-23 13-47-00

Removing this 2 lines makes it work again, but don't know why ion components are creating this behaviour.

So the issue here is due to hydration of Ionic components. By default, your app has the following CSS:

html {
  visibility: hidden;
}

When your app is hydrated, the html element gets the hydrated class applied which gives the following CSS:

html.hydrated {
  visibility: visible;
}

All Ionic components inherit this visibility. So for example, if your app is not hydrated, ion-content will not show. As a result, your sign in form will not show up either.

The behavior your are seeing is due to the transition value that you pointed out earlier. The following CSS:

.signin-signup {
  transition: 1s 0.7s ease-in-out;
}

Gets computed as:

transition-duration: 1s;
transition-property: all;
transition-timing-function: ease-in-out;
transition-delay: 0.7s;

The key here is the transition-delay. When changing visibility: hidden to visibility: visible, the transition kicks in since it is applied to all properties. visibility does not "animate" in like opacity does, so the affected elements will just appear instead. Since you have a delay of 0.7s, the browser will wait 0.7s before showing the elements, resulting in the behavior you experienced.

To verify this, try changing 0.7s to 10s. You should notice that the sign in form takes even longer to show up now. Additionally, to verify that this is due to visibility changing, try adding visibility: visible to .signin-signup and you should notice that the form appears instantly.

The next mystery is why this happens when ion-spinner is present. My best guess is the inclusion of this component requires additional processing time that causes the visibility to change in two different frames, causing the transition to take effect. I have a minimal version of your app running and if I refresh several times, sometimes the issue happens and sometimes it does not. If the visibility is set to hidden and then set to visible in the same frame, the transition should not take effect.

While I do not think this is a bug in Ionic Framework, it certainly is pretty confusing. My recommendation is to be specific with what your transitions apply to as the default is to have the transitions apply to every property. So for transition: 1s 0.7s ease-in-out;, consider having it apply to specific properties such as opacity or transform instead.

I am going to close this issue out. Thanks!

Thanks very much for the explanation, it was very confusing to me why it only happened with the ion component, so I thought it was an ionic bug. Now I do understand what the bug was, thank you very much.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manucorporat picture manucorporat  路  3Comments

brandyscarney picture brandyscarney  路  3Comments

fdnhkj picture fdnhkj  路  3Comments

giammaleoni picture giammaleoni  路  3Comments

BilelKrichen picture BilelKrichen  路  3Comments