Prerendering + lazy loading friction
See original GitHub issueI’m submitting a … (check one with “x”)
[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior In the context of a SPA which uses server-side pre-rendering (such as implemented in the dotnet generator, see this guide also) and lazy-loaded routes, there is a moment after the app is bootstrapped and the lazy-loaded module is downloaded or downloading when neither the module nor the pre-rendered content are visible. This is jarring enough to make the pre-rendering detrimental rather than beneficial.
- user loads app on lazy-loaded route
- prerendered content is loaded, user starts reading
- app core content is loaded and bootstrapped
- app renders without lazy route – prerendered content disappears without its replacement
- app starts downloading the lazy route
- lazy route finishes loading, is rendered – content reappears
Expected behavior The handover should be seamless. Maybe there could be a configuration where no angular rendering happens until all lazy loading is finished.
Minimal reproduction of the problem with instructions
- Create a new Angular2 project (with pre-rendering or substantial placeholder content)
- Create a lazy-loaded route and the corresponding router configuration
- Load corresponding route directly
repro (uses alerts to illustrate pain points, remove them to see issue in action)
What is the motivation / use case for changing the behavior? To reap benefits of both lazy loading and server-side pre-rendering
Please tell us about your environment: essentially the dotnet generator, but see repro for a more agnostic example.
-
Angular version: 2.0.X 2.1.0 (my working copy) & 2.0.0 (repro)
-
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] Chrome 54.0.2840.71 m (64-bit) Firefox 49.0.1 Edge 38.14393.0.0
-
Language: typescript
-
Node (for AoT issues):
node --version
= v4.6.0
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
If anyone else stumbles on this and needs a quick fix before it’s resolved, here’s a stopgap that guesses and loads a route based on window.location. (Would have to be fleshed out a bit for a more complex routing situation, eg, with multiple outlets, but handles nested lazy routes, a single route param, and redirectTo.)
https://gist.github.com/daveriedstra/145519e3919795ba8c6438ba4df2a812
this is a problem with how lazy loading is designed and how we split our code. To fix this it is easy since we just have to preload our lazy routes before bootstrap. See fix below
https://plnkr.co/edit/xjXFse?p=preview
it would be great if we could pass an option to allow preloading to block bootstrap https://github.com/angular/angular/blob/491d5a22a9dc1082e80aa5ca481aa02b49b9bfe8/modules/%40angular/router/src/router_module.ts#L281 the lone above would have to return a Promise.all of the routes if an option was set
The real fix is a better way to bundle your code where lazy load the other pages that are rendering. Right now everything is hardcoded to the index page being the initial rendered page while everything else is split. The build system would have to create bundles/splits for each page and also change the values of each child module path and parent module path