ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.51k forks source link

bug: SSR, Flickering when ssr page is replaced #21394

Closed KevinBassaDevelopment closed 7 months ago

KevinBassaDevelopment commented 4 years ago

Bug Report

Ionic version: [x] 5.0.5

Current behavior: When the app switches from server side rendered to client side rendered version, there is is a blank screen shown, resulting in a flickering on fast-loading devices.

This is not the case when using angular universal without ionic.

Expected behavior: The user should not recognize the switch, as with original angular universal apps.

Steps to reproduce: Create Angular SSR application. Add Ionic.

Example To see it more clearly, check this example (25s video) where I used a slow network speed. Between "IsServer -> IsBrowser", a blank page appears.

ionic-ssr-flicker

A sample application via GitHub Github Ionic-SSR-Flickering Github Angular-SSR-No-Flickering

The live examples can be compared here: Live Ionic SSR example Live Angular SSR example

I opened a new ticket because my existing ticket was closed as it was initially missing an example. #21245

mhartington commented 4 years ago

Thank you for the detailed demo! After talking with the team a bit, this will likely require a refactor in how our components are loaded to address this. At least from looking at it quickly..

KevinBassaDevelopment commented 4 years ago

Just to add why this really is a problem for anyone using SSR:

The advantage of SSR is that the user thinks at the First Meaningful Paint that the application is fully ready. This is typically at <1 second.

Now here he clearly sees the loading process until the Time to Interactive is finished, which is typically 3x the first value.

So the visual performance is now reduced to a 1/3 of what it could be, making SSR Ionic applications slower than not using SSR at all.

The example above is super small, making everything very fast, but for big applications it is very recognizeable.

hamletborn commented 4 years ago

thank you @KevinBassaDevelopment for your demo ,I meet the same issue If the page has a ajax request will see the flickering ,wish to fix this issue

shahramSo commented 4 years ago

I tested in an Ionic Sidemenu starter app version 5 with Angular 9 ivy, it doesn't work correctly in menu side when javascript is disabled. The menu side is not appeared.

playvue commented 4 years ago

Still having this issue on ionic 5.3.1/ng 10.1, has there been any progress?

ionic info

Ionic:

   Ionic CLI                     : 6.11.0 (/usr/local/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 5.3.1
   @angular-devkit/build-angular : 0.1000.7
   @angular-devkit/schematics    : 10.0.7
   @angular/cli                  : 10.1.0
   @ionic/angular-toolkit        : 2.3.2
materazu commented 4 years ago

Same, we using ionic's angular-server technics to build our app, who using stencil as a design-system through Angular. It's the same case, server rendering is good and appear in window, but after we have a glitch when Angular load the app.

Maybe anyone can help with this topic?

agustinhaller commented 4 years ago

I'm experiencing the same issue with the following Ionic version:

Ionic info:

Ionic:

   Ionic CLI                     : 6.11.8 (/Users/agustin/.npm-global/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 5.3.3
   @angular-devkit/build-angular : 0.1001.2
   @angular-devkit/schematics    : 10.1.2
   @angular/cli                  : 10.1.2
   @ionic/angular-toolkit        : 2.3.3

Capacitor:

   Capacitor CLI   : 2.4.1
   @capacitor/core : 2.4.1

Utility:

   cordova-res (update available: 0.15.1) : 0.11.0
   native-run                             : not installed

System:

   NodeJS : v12.14.1 (/usr/local/bin/node)
   npm    : 6.14.8
   OS     : macOS Catalina

I've invested quite some time trying to understand what was really going on behind this bug in the hopes of adding value to this conversation and maybe get us a step closer to fixing this issue.

Debugging the main.ts file, I identified the following:

// 1 - SSR version of the app loaded [content OK]

document.addEventListener('DOMContentLoaded', () => {
  // 2 - DOMContentLoaded triggers [content OK]

  setTimeout(() => {
    // 3 - Before AppModule get’s bootstrapped [First flick (partial)]
  }, 100);

  platformBrowserDynamic().bootstrapModule(AppModule)
  .then(() => {
    // 4 - Immediately after the AppModule get’s bootstrapped [Second flick (full)]

    setTimeout(() => {
      // 5 - Some instants after AppModule get’s bootstrapped [content OK]
    }, 300);
  })
  .catch(err => console.log(err));
});
  1. Load SSR version of the app (comes from the server with .hydrated classes). Everything looks OK.

  2. DOMContentLoaded triggers.

  3. First flick (partial): Before AppModule get’s bootstrapped on the browser, it seems to be an issue with the transition from the emulated shadow dom from the SSR and the actual shadow dom when transitioning to the browser. All the content inside shadow dom disappears (and that’s what causes the blank screen flick). I suspect it has something to do with the shadow dom, because if I put some content (a heading) outside the shadow dom, it doesn’t disappear.

I think this first one is a partial flick because all the content outside the shadow dom seems to be intact.

  1. Second flick (full): Immediately after the AppModule get’s bootstrapped, some components lose the hydrated class (ie: <ion-page>). This causes everything inside those components to be hidden.

  2. Some instants (couple milliseconds) after AppModule get’s bootstrapped, all hydrated classes are properly set again, causing the content to be visible again.


In the process I have discarded some of the hypothesis I found around the web. In my experience:

Note: In the current production version of my app I have implemented all the previously mentioned solutions and the flick is still happening.

I'm basically sharing my experience so others don't waste time (like I did) trying solutions that are dead ends.

Hope the time I invested analyzing the situation helps move this forward.

sean118 commented 4 years ago

Has anyone come up with an idea yet on how to fix this? How exactly would an ionic component have to be loaded differently to get rid of this flicker?

signuspl commented 3 years ago

I have tested my app with Ionic 5.6 and still having this issue. The flick is still happening and for a big app with many components at home screen this looks like very bad ux. For this moment we use SSR only for search engines bots - for regular user it is better to show loading screen and wait for the app.

Maybe you have any progress with this issue?

isaiahdahl commented 3 years ago

@liamdebeasi @mhartington Would love to see this bump up in priority. Been watching these issues since the beginning of Ionic Angular SSR support. We initially had an Angular Universal app and when ionic came out with support for SSR we moved the whole app to Ionic app only to discover this LAME trade-off, we went with it hoping such a core issue would get resolved but it's been a year. This doesn't feel like full SSR support with Angular and Ionic. The experience on the front end feels like such a hack right now.

adamgasiorek commented 3 years ago

@mhartington please let us know, what is a progress with this problem. There are still people waiting for this feature .... ( with flickering this is useless )

piotrbarandeveloper commented 3 years ago

(up) Can we expect a fix for this problem in the new release ionic v6?

liamdebeasi commented 3 years ago

Hi everyone,

Quick update on this issue:

We believe this flickering issue will be reduced with changes in Ionic Framework v6. Our components will no longer use Stencil’s lazy loading, so the flash of unstyled content should disappear. This should translate into a noticeable improvement in flickering when using Ionic Framework and Angular Universal.

We are in the process of moving off Stencil’s lazy loading for Ionic Angular, so we are going to keep this issue open for now but will re-evaluate as we do more testing. I am going to lock this thread since we have a good understanding of the use cases and the impact this issue has on the community. We will update this thread when we have more to share. Thank you!

liamdebeasi commented 7 months ago

Hi everyone,

Apologies for the delay. With the introduction of Ionic Angular standalone components, this behavior should be improved. The standalone components do not make of Stencil's lazy loading which will help reduce any flickering. See https://ionicframework.com/docs/angular/build-options for information on how to get started with Ionic Angular standalone components. I am going to close this, but let me know if there are any questions.