ionic-framework
ionic-framework copied to clipboard
bug: Angular: Components that are lazy loaded for the first time are not hydrated immediately
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
- [ ] v4.x
- [ ] v5.x
- [X] v6.x
- [ ] Nightly
Current Behavior
Disclaimer: This may be expected behaviour to prevent layout shift but I cannot find any documentation regarding this and solutions on how to get around this.
When navigating to an angular route with an ion-list (will possibly apply to any ion component) in an ion-card, all contents of the card do not display until the ion-list has been fetched from the server. This is especially noticeable on slow connections.
"preloadingStrategy: PreloadAllModules" does not solve this issue
Expected Behavior
Available ion-card content should be visible while lazy loaded components are fetched from the server.
Steps to Reproduce
Open the code reproduction URL below. Once opened, set your network performance to "Slow 3G" in Chrome dev tools. Click the "Show list" link. Observe the "Page load start" text displays immediately. The "Card content" text only displays once the ion-list has loaded.
In view-message.page.html, comment out the
Reload the app starting from the home page. You may want to reset your network to "No throttling" while doing this
Set the network back to "Slow 3G"
Observe that "Card content" loads as soon as the page opens when clicking the "Show list" link
Code Reproduction URL
https://stackblitz.com/edit/angular-ivy-rnqahb?file=src%2Fapp%2Fhome%2Fhome.page.html
Ionic Info
All info is in the stackblitz demo
Additional Information
I can make the
@dexster thanks for reporting this issue!
The behavior you are observing is the effect of the lazy-hydrated bundle from Stencil that is used in our @ionic/angular
package.
Web components are lazily requested and defined, as they are used in the DOM. Since you are lazy loading the modules for routing, ion-list
is not requested in the DOM until that route is resolved.
Unfortunately, there isn't a great workaround here other than including the element in the DOM and hiding it, like you have done in your commented out example.
In v7 we are moving away from the lazy-hydrated bundle for Angular and moving to the custom elements build, which is currently leveraged by @ionic/react
and @ionic/vue
. With that, you should not have any delay in rendering in your scenario, as web components are either defined upfront on bootstrap or upon DOM request (without a hydration cycle from Stencil).
I'll leave this issue open and classify it, as I do believe our efforts in the next major release should resolve this. In the event I am wrong, other team members can add their thoughts of appropriate workarounds/configurations to avoid this problem.
Thanks for the feedback.
The main issue I am having is the ion-card not displaying until inner components are loaded. Preloading the components upfront does help but wouldn't it be preferable to not prevent the card from rendering while inner components are hydrated/loading? I use ion-cards in previous screens so it's already loaded. Or does the whole card/list become the lazy hydrated bundle you mentioned?
If this is already part of your efforts you mentioned then I'm happy to wait.
FYI,
Apart from adding a few preloaded ion components to my page with "display: none" I also had to do this so that my loading spinner worked correctly otherwise I would navigate to a page and no spinner was shown because it was busy loading when it should have been spinning
preloadLoaderHack() {
this.loadingController
.create({
spinner: 'circular',
showBackdrop: false,
cssClass: 'pre-load',
})
.then((loader) => {
loader.present();
loader.dismiss();
});
}
I see this still happens with v7.
@sean-perkins any timeline for utilizing custom elements build in Angular library? This would also allow using the new esbuild/vite compiler with Angular.
Hi everyone,
We recently released Ionic components as Angular standalone components in Ionic 7.5.0 which makes use of the new build system Sean mentioned in https://github.com/ionic-team/ionic-framework/issues/25646#issuecomment-1185747390. The documentation for this feature is available here: https://ionicframework.com/docs/angular/build-options
This build system doesn't use hydration, so the original issue should not occur when using Ionic components as standalone components. I recommend using this feature if you would like to avoid hydration. I am going to close this issue, but let me know if there are any questions.
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.