-
Notifications
You must be signed in to change notification settings - Fork 12
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
[progressive hydration] self hydrating custom elements #33
Comments
interesting approach - that certainly gives absolute freedom on how every component wants to be hydrated... this flexibility is however also what I would be afraid off what happens
hmmm I think that is more an outside concern... as a web component author I do not really need to know if I am loaded directly or only on mobile... and I certainly don't wanna write that code... but yeah getting that freedom if needed would be nice 🤔 |
Thanks for taking time to review! 👋
10 instances of the same custom element, or 10 unique custom elements all defining a If the former, then the That said, I'm not really sure the cost of setting up an IntersectionObserver, so that is definitely a good call out, but I think whether the author defines it or the framework defines it, the overhead would be the same right? The advantage for this approach to the user is that this would only ship the 2,3,10 lines of code in that
I'm not sure if it's possible, but I think maybe just decorating the base class in userland on the server could work? import { SomeComponent } from '@some/component';
SomeComponent.__hydrate__ = () => {
// do stuff
}
Each custom element definition that would want to participate in this protocol would define its own I don't think I would want components sharing the logic of a single IntersectionObserver predicate as each custom element is likely going to want to control its own hydration behavior, but certainly nothing would stop you if that is the effect you wanted to achieve.
Yeah, that's a good point. As a a library author, I wouldn't always know the context my component is being used in. Since custom elements are just classes, I suppose perhaps the user of the WC could just set that themselves , like in the example above re: defining a
Indeed! I think at least at this stage one thing to keep in mind is, I'm not sure any of these strategies are clear cut winners at all (yet). I think the general consensus is that hydration as a technique can be improved to better take advantage of the initial server work, but how it will play out in practice and what that looks like, will take some more time. And likely, it could be a combination of strategies, and likely different depending on the scenario. I think the best thing that can happen is to crowd-source the exploration and discovery space as much as possible to get lots of examples and possibilities out there, test them in apps, then hopefully whittle it down to an accepted community protocol(s). 🤞 |
I'm a little confused by the example implementation. If the code is run in the browser and a |
Yeah, for this kind of implementation, the SSR framework would need to statically analyze / compile the component definition and extract the logic from it, and add it to the initial HTML for the page, in an inline |
Overview
As an alternative / complementary approach to #30 , I had been thinking about what it could look like if instead of the framework / runtime being the handler of the hydration, syntax, DSL or to avoid being an opinionated wrapper around Intersection / Mutations observers.
What if custom elements had the opportunity to self define their own hydration logic? The premise is that a custom element would define a
static __hydrate__
method (or whatever) that could be used to encapsulate its own hydration, loading, etc logic, and then the SSR framework mechanism (e.g. community protocol) would just need to extract this logic and inject that it into the runtime.Example
Given this sample component
What's nice is that anything could go here since you have full access to the browser, like for IntersectionObserver, MutationObserver, addEventListener, etc. Plus, the runtime overhead is entirely sized by the user, so no extra JS gets shipped except for what the user themselves chooses to include.
So for this scenario, you could just use it as
and in action, it would look like this
wcc-ssr-self-hydration.mov
Observations
So looking to the above recording, we can observe that we get an alert when the hydration logic runs, even though test.js has not loaded. when we scroll down to the intersecting point, test.js loads the custom element, which then initiates the color change and CSS animation.
I think what’s neat is that at a top level, you could still set attributes on static HTML, maybe to preload some data or state, if you’re already running a single pass over the HTML. So could make for a really nice combination of techniques and potentially open the door up to more complex strategies like partial hydration, or resumability, which is even nicer when you think about that you could include a
<script type="application/json">
inside a Shadow DOM... 🤔Feedback
Some good call outs so far to investigate:
__hydrate__
method to a custom element's base classThe text was updated successfully, but these errors were encountered: