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

[Angular] Asynchronously render lazily loaded components #898

Open
apoteet opened this issue Dec 21, 2021 · 0 comments
Open

[Angular] Asynchronously render lazily loaded components #898

apoteet opened this issue Dec 21, 2021 · 0 comments
Labels
backlog Issue/PR/discussion is reviewed and added to backlog for the further work keep

Comments

@apoteet
Copy link

apoteet commented Dec 21, 2021

Is your feature request related to a problem? Please describe.

I've spotted an issue in jss-angular where if you have eagerly AND lazily loaded components inside a placeholder, the lazy components will block the entire placeholder from rendering until the lazy scripts have been downloaded. If you zoom out all the way and refresh, you should see the page load, and a chunk of components vanish, and then show up again a moment later. The page is first rendered server-side in node, and then when the browser code takes over, it clears the page while the placeholders rerender. This kills our CLS score in Google's Lighthouse and causes extra download because lazily loaded images and scripts lower on the page pop in, since the placeholder above hasn't loaded yet.

This is happening because the placeholder component first waits to get all of the component definitions before rendering.
https://github.com/Sitecore/jss/blob/dev/packages/sitecore-jss-angular/src/components/placeholder.component.ts#L211-L226
with the help of componentFactory.getComponents(placeholder) waiting for all promises to resolve.
https://github.com/Sitecore/jss/blob/dev/packages/sitecore-jss-angular/src/jss-component-factory.service.ts#L113-L122

Describe the solution you'd like

It would be great if we could put components on the page as their definitions are ready. So eager components would appear right away, while lazy components appear as their promises resolve. I think the componentFactory would need a function for getComponents(placeholder) that returns an array of promises, which the placeholder component would iterate over and apply then() callbacks to each to render the component. The biggest challenge might just be preserving the rendering order.

Describe alternatives you've considered

At the moment, I have changed that one lazy component on our home pages to be eagerly loaded so we don't have that flickering effect.
I also considered adding a route to our app routing module to prefetch that one component chunk for the "/" route, but figured adding routes would have more side effects.
At the moment, I think this behavior makes lazy loading hurt sites that care about Google Lighthouse scores, specifically the CLS metric. This influences SEO.

Additional information

Snapshot of one of our container placeholders not showing up on a zoomed out page on a throttled connection, because one of the 4 components there is lazily loaded. The three spans of white text on gray boxes are an eager component that is supposed to be much farther down the page
image

Or if i'm just horribly confused and doing something wrong, please let me know!

Edit: Removed example page as it was worked around long ago

@illiakovalenko illiakovalenko added the backlog Issue/PR/discussion is reviewed and added to backlog for the further work label Jul 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog Issue/PR/discussion is reviewed and added to backlog for the further work keep
Projects
None yet
Development

No branches or pull requests

3 participants