Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
[defer-hydration] Initial draft #15
[defer-hydration] Initial draft #15
Changes from 3 commits
e9ec4f4
8fad97c
1419cc3
517045a
00c78d7
5623940
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
A couple minor grammatical point(s)
change from
to
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.
Can you explain why this is (why they shouldn't automatically hydrate)? Is there an example where doing so would create unwanted results?
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 could see this fitting into a "when work gets done" topic of conversation by allowing islands to be linked generally by component name, while still being able to disambiguate on which of those islands are needed at any one time. Much like Astrobuild leverages the
:visible
modifier to control when the code for a component is loaded, this could allow other instances of the component on the same page the ability upgrade with the initially visible instance, and then wait to hydrate until they, too, are in view.I think this sort of laziness deserves to be revisited more thoroughly a the browser spec level. This seems roughly in line with the a proposal around lazy definitions: WICG/webcomponents#782 and could arguably fit into a larger conversation around the browser allowing for lazy upgrades, which would be somewhat similar to what this protocol looks to support.
Regardless, if you're SSR'ing the entirety of an element that may not come into view, the ability to control when it reconciles that delivered SSR render with the client-side render sounds like a good idea.
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.
Sorry for just now getting back to this, but why would you want to delay rendering a component? The reason for those modifiers are to:
The reason is not to delay rendering. Rendering should be relatively cheap, especially if the component was prerendered, there's no work to do but set up the event listeners.
It is, of course, possible that some components are going to be more expensive than others, but that's reason for those particular components to have their own API to delay rendering, not to make it a standard that is used arbitrarily.
The goal is to make the page as interactive as possible. Delaying rendering without good reason should be avoided.
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.
Again, the main reason is to enable top-down initialization, even for spontaneous first renders. We need our components to initialize in the same order whether CSR'ed or SSR'ed, independent of definition order.
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.
That's a different use case (being discussed below). The island orchestration use case is another, it's why Eleventy/webc has adopted this for example.
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 guess this is maybe a partial answer for (1)? Should these be separate points, if so?
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 more I think about it, I don't think I agree with this point (2), cc @Westbrook. I would expect that in most cases an element's initial data has been serialized as attributes and doesn't need the parent to pass that information. The exception would be data that isn't serialized, like complex objects, but I don't think that's really the norm.
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 https://github.com/w3c/webcomponents-cg has a breakout session to discuss Community Protocols, that could certainly include this, at the beginning of next month. Would you be interested in joining the call? Would be great to get your thoughts on this, and many other of the topics we're discussing right now "in person"!
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.
Yeah I could probably attend that.
Just for clarity, I'm not against this proposal, just trying to understand the scenarios in which it is needed. The text could help by clarifying that a bit more.
My thinking is that a typical usage would not need this because:
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.
Curious on folks perspective around
defer-hydration
as compared to something akin toloading="lazy"
If the attribute was, say,
hydration
, with options like:defer
: Hydrates based on internal behaviorlazy
: Hydrates based on when in viewporteager
: Default behaviorShould the attribute control both the intended behavior and the current state? Some tools use
:visible
, Stencil uses thehydrated
class for hydrated state.Decoupling this and setting a convention around the intended behavior and leaving how state is communicated up to the tools might be helpful.
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.
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.
visibility
is such a hot/important topic for upgrade/hydration that we should probably include it in line withsuch as interacting with an element
.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.
One thing that's not clear to me from this proposal: what does "hydration" mean? Just
connectedCallback
? Orconstructor
plusconnectedCallback
?I'm assuming that it only means
connectedCallback
, but you could imagine that a web component could have some logic in itsconstructor
that assumes client-side rendering, which assumes top-down rendering, and thus breaks whencustomElements.define
is called out-of-order.Is this situation considered out-of-scope for this proposal?
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.
Hydration is going to be component or library specific, and I'm not sure it will have a precise definition besides making the component "go".
For instance, in Lit's case hydration is fairly coarse grained, but per component. It means the component is fully initialized - the templates are ready to receive updates, event listeners are attached, and our deferred connectedCallback is called which can then fire events, etc.
Yes, absolutely this could happen. I don't think all components will be SSR and hydration compatible without adhering to some rules. I expect a lot of teams will control all their components, or use a base class that helps, or maybe we'll see utilities that proxy or late-register components that need it.
It's out of scope for this proposal in that this proposal is about an opt-in interoperable signal that the component should do whatever it deems appropriate at this point in time, and that's about the most I think we can do. It'll always be up to the components to choose what to do then.
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.
Thanks for the clarification. It might be good to nail down some SHOULDs in this case (not necessarily MUSTs). E.g., thoughts that pop into my head are:
connectedCallback
fire in a deferred way?renderedCallback
for when the DOM is rendered, Lit has various callbacks likeupdated
/firstUpdated
/etc.connectedCallback
code fires? ShoulddisconnectedCallback
fire beforeconnectedCallback
, or not at all?