-
Notifications
You must be signed in to change notification settings - Fork 16
Open
Description
First Level hydration
This is a proposal for a "syntax" of conditions to trigger hydration of a component.
It has 3 separate "states":
- server (only render it server-side => do not ship any js) [probably framework specific]
- client (do not touch server-side and ship js) [probably framework specific]
- hydrate (render server-side and at some point do loading! + rendering on client-side)
For server/client
there are no additional "options"... but for hydrate, there are multiple modifies you could combine
Mode | Option | Description |
---|---|---|
server | render server-side and do not hydrate (default) | |
client | do not touch server-side and render client side | |
hydrate | 👇 | render server-side and at some point do loading + rendering on client-side |
onClientLoad | [1] as soon as possible | |
onClick | [1] as you click on the element | |
onMedia | [2] as soon as a media query is met | |
onVisible | [2] as soon as component + optional padding becomes visible | |
onHover | [2] as you hover over the element + optional padding (click triggers hover => touchscreens) | |
onIdle | [3] as soon there is a free slot in the main thread | |
onDelay | [3] after x ms |
[1]: global events: implemented via a single global event handler
[2]: element events: every element needs its own event handler
[3]: modifiers: modify how/when the hydration happens AFTER all conditions are met
Hydrate condition combinations
Each of the options can be combined via &&
or ||
.
Example | Description |
---|---|
loading="server" |
non interactive components like layouts or graphical components (= default) |
loading="hydrate" |
most components should hydrate as soon there is a free slot in the main thread |
loading="hydrate:onIdle" |
same as 👆 |
loading="hydrate:onClientLoad" |
above the fold element that should become interactive as soon as possible |
loading="hydrate:onMedia('(max-width: 320px)')" |
mobile burger menu that triggers a drawer for navigation (only hydrate on screens smaller then 320p) |
loading="hydrate:onMedia('(min-width: 640px)') && onClick" |
chart that only becomes interactive on desktop after a click |
loading="hydrate:onMedia('(prefers-reduced-motion: no-preference)') && onClick" |
a visual animation that plays on click only if there is no prefers-reduced-motion |
loading="hydrate:onVisible && onIdle" |
heavy chart that becomes interactive when element becomes visible |
loading="hydrate:onVisible(100px)" |
heavy chart that becomes interactive when element + 100px padding becomes visible |
loading="client" |
components that do something that can not be server rendered (for example need to access cookies or localStorage) |
sadly this does not prevent "useless" combinations like loading="hydrate:onVisible && onClick && onHover"
.
Inspired by withastro/roadmap#108 and slinkity/slinkity#20
Example of user code
<h1>Rocket Blog</h1>
<inline-notification>Do this</inline-notification>
<!-- 👆 will be only server rendered -->
<my-hero loading="hydrate:onClientLoad">
Welcome ...
</my-hero>
<!-- 👆 server render + hydrate as soon as possible -->
<my-list loading="hydrate"></my-list>
<!-- 👆 server render + hydrate if main thread is idle -->
<my-chart loading="hydrate:onVisible"></my-chart>
<!-- 👆 server render + hydrate as element becomes visible -->
<my-heavy-chart loading="onVisible || onMedia('(min-width: 768px)')"></my-heavy-chart>
<!-- 👆 server render + hydrate -->
<!-- desktop: hydrate immediately (matches media query) [could add && onIdle] -->
<!-- mobile: hydrate as element becomes visible -->
<my-heavy-graph loading="hydrate:onMedia('(min-width: 768px)') && onVisible || onClick"></my-heavy-graph>
<!-- 👆 server render + hydrate -->
<!-- desktop: hydrate as element becomes visible -->
<!-- mobile: hydrate on click (to safe bandwidth) -->
<my-login loading="client"></m-login>
<!-- 👆 only client render -->
anoblet, jorgecasar, thescientist13, sashafirsov, bahrus and 1 morethescientist13
Metadata
Metadata
Assignees
Labels
No labels