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
feat: lazy hydration #26468
base: main
Are you sure you want to change the base?
feat: lazy hydration #26468
Conversation
Run & review this pull request in StackBlitz Codeflow. |
β¦ future wrappers
unobserve = null | ||
}) | ||
return () => h('div', { ref: el }, [ | ||
isIntersecting.value ? h(componentLoader, attrs) : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to lazy hydrate or to lazy load here ?
Lazy hydration would need to render the component in SSR. Keep it "static"/non-interactive in client until loaded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont actually know, which is better here? Do we want all of these wrappers to lazy load as opposed to lazy hydrate? Can this be lazy loaded via
h(await import(compName))
?
Or should the logic of defineAsyncComponent that we added in loader.ts be moved to inside the h?
From the current implementation I'm assuming it's lazily hydrated (please correct me if I'm wrong), but I suppose we should make performance tests to see which is better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more about how createClientIO
should work.
The issue with the current state is that it is a client-only until observed because it is never rendered in SSR. So when missused, end users can experience a reduced UX (like when using CLientOnly
). And also having an reduced webperf score if the lazyhydrated component is within the viewport at loading.
I think what #24242 was expecting is to render the component in SSR and then hydrate when observed.
So we could probably render the component in server side. Then until observed, it would be a static vnode (you can check how to do it in nuxt-island). Once observed, you'll be able to render the component.
I think the PR probably just need some changes within createClientIO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: didn't see you responded. I'll take a look at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue with the current state is that it is a client-only until observed because it is never rendered in SSR. So when missused, end users can experience a reduced UX (like when using CLientOnly). And also having an reduced webperf score if the lazyhydrated component is within the viewport at loading.
Though the question here would be, would lazy loading not inherently provide better performance as opposed to lazy hydration? We can use a static vnode of course, but wouldn't lazy loading still reduce bundle? Of course everything can be misused, it's up to the individual developers to use the tools as intended.. There is no reason to make components inside the viewport async regardless, that in and of itself would hurt performance, even if it doesn't use any special wrappers. How can it hurt UX, especially if used properly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more about the meaning behind "lazy hydration", in my opinion it implies that the component is still rendered in SSR.
The current implementation is more like a "lazy component until in viewport" π€ .
Though the question here would be, would lazy loading not inherently provide better performance as opposed to lazy hydration?
Probably slightly better with lazy loading. But rendering a static vnode isn't very costly in term of performance.
There is no reason to make components inside the viewport async regardless, that in and of itself would hurt performance, even if it doesn't use any special wrappers. How can it hurt UX, especially if used properly?
Indeed but some users may use it for a component that is in small breakpoint -> meaning that in desktop it would load the component after the page load resulting in some layout shift.
π Linked issue
#24242
β Type of change
π Description
Lazy loading is a very beneficial addition to the nuxt core. Natively supporting delayed hydration will provide significant performance improvement. Moreover, it will reduce the amount of boilerplate code needed for manual implementations, and will reduce bundle size by not requiring external modules for something that may very well be handled out-of-the-box, as part of the
Lazy
components behavior.π Checklist