From e9ec4f4eaa1a4dc4cf3c2b11c04e42939494cdb6 Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Thu, 24 Jun 2021 15:59:16 -0700 Subject: [PATCH 1/5] [defer-hydration] Initial draft --- README.md | 8 +++++--- proposals/defer-hydration.md | 21 +++++++++++++++++++++ proposals/pending-task.md | 4 ++-- 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 proposals/defer-hydration.md diff --git a/README.md b/README.md index 1a4fafe..6292767 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,13 @@ Check out the [Issues](https://github.com/webcomponents/community-protocols/issu ## Proposals -| Proposal | Author | Status | -|-----------------|----------------|--------| -| [Pending Task] | Justin Fagnani | Draft | +| Proposal | Author | Status | +|-----------------|----------------|-----------| +| [Pending Task] | Justin Fagnani | Draft | +| [Pending Task] | Justin Fagnani | Proposal | [Pending Task]: https://github.com/webcomponents/community-protocols/pull/1 +[Defer Hydration]: https://github.com/webcomponents/community-protocols/pull/15 ## Status diff --git a/proposals/defer-hydration.md b/proposals/defer-hydration.md new file mode 100644 index 0000000..c487872 --- /dev/null +++ b/proposals/defer-hydration.md @@ -0,0 +1,21 @@ +# Defer Hydration Protocol + +An open protocol for controlling hydration on the client. + +Author: Justin Fagnani + +Status: Draft + +Last update: 2021-06-24 + +# Background + +In server-side rendered (SSR) applications, the process of a component running code to re-associate its template with the server-rendered DOM is called "hydration". We want to enable interoperable incremental hydration across web components, so that componentents do not automatically hydrate upon being defined, but wait for a signal from their parent or other coordinator. + +The enables us to decouple loading the code for web component definitions from starting the work of hydration, and enables sophisticated coordination of hydration, including triggering hydration only on interaction or data changes for specific components. + +# Overview + +The Defer Hydration Protocol specifies an attribute named `defer-hydration` that is placed on elements, usually during server rendering, to tell them not to hydrate when they are upgraded. Removing this attribute is a signal that the element should hydrate. Elements can observe the attribute being removed via `observedAttribute` and `attributeChangedCallback`. + +When an element hydrates it ca remove the `defer-hydration` attribute from its shadow children to hydrate them, or keep the attribute if itself can determin a more optimal time to hydrate all or certain children. diff --git a/proposals/pending-task.md b/proposals/pending-task.md index 5754c19..cbf6ebf 100644 --- a/proposals/pending-task.md +++ b/proposals/pending-task.md @@ -6,7 +6,7 @@ Author: Justin Fagnani Status: Draft -Last update: 2021-066-20 +Last update: 2021-06-20 # Background @@ -166,4 +166,4 @@ Some use cases, like a progress bar that shows how much work is remaining, could The `pending-task` event could carry a numeric work estimate property so that containers can estimate the total amount of pending work and incremental progress. -On the other hand, this may be better suited for ProgressEvent. \ No newline at end of file +On the other hand, this may be better suited for ProgressEvent. From 8fad97cfe39dd89fc1ca25e7718a9f6e7e09819f Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Thu, 24 Jun 2021 17:42:52 -0700 Subject: [PATCH 2/5] More details and examples --- proposals/defer-hydration.md | 75 ++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/proposals/defer-hydration.md b/proposals/defer-hydration.md index c487872..8cacb95 100644 --- a/proposals/defer-hydration.md +++ b/proposals/defer-hydration.md @@ -10,12 +10,81 @@ Last update: 2021-06-24 # Background -In server-side rendered (SSR) applications, the process of a component running code to re-associate its template with the server-rendered DOM is called "hydration". We want to enable interoperable incremental hydration across web components, so that componentents do not automatically hydrate upon being defined, but wait for a signal from their parent or other coordinator. +In server-side rendered (SSR) applications, the process of a component running code to re-associate its template with the server-rendered DOM is called "hydration". The defer-hydration protocol is design to allow controler over hydration to solve two related problems: -The enables us to decouple loading the code for web component definitions from starting the work of hydration, and enables sophisticated coordination of hydration, including triggering hydration only on interaction or data changes for specific components. +1. Interoperable incremental hydration across web components. Componentents should not automatically hydrate upon being defined, but wait for a signal from their parent or other coordinator. +2. Hydration ordering independent of definition order. Because components usually depend on data from their parent, and the parent won't usually set data on a child until it's hydrated, we need hydration to occur in a top-down order. + +`defer-hydration` enables us to decouple loading the code for web component definitions from starting the work of hydration, and enables top-down ordering and sophisticated coordination of hydration, including triggering hydration only on interaction or data changes for specific components. # Overview The Defer Hydration Protocol specifies an attribute named `defer-hydration` that is placed on elements, usually during server rendering, to tell them not to hydrate when they are upgraded. Removing this attribute is a signal that the element should hydrate. Elements can observe the attribute being removed via `observedAttribute` and `attributeChangedCallback`. -When an element hydrates it ca remove the `defer-hydration` attribute from its shadow children to hydrate them, or keep the attribute if itself can determin a more optimal time to hydrate all or certain children. +When an element hydrates it can remove the `defer-hydration` attribute from its shadow children to hydrate them, or keep the attribute if itself can determine a more optimal time to hydrate all or certain children. By making the parent responsible for removing the `defer-hydration` attribute from it's children, we ensure top-down ordering. + +## Use case 1: Auto-hydration with top-down odering + +In this use case we want to page to hydrate as soon as elements are defined, but we want to force top-down ordering to avoid invalid child states. Here we configure the server-rendering step to add the `defer-hydration` attribute to all elements _except_ the top-most defer-hydration-aware elements in the document. + +When the top-most elements are defined, they will run their hydrations steps since they don't have a `defer-hydration` attribute, and will trigger their subtrees to hydrate by removing `defer-hydration` from children. + +Example HTML: + +```html + + + + + + + + + + + + + +``` + +## Use case 2: On-demand hydration + +Hydration can be deferred until some data or user-driven signal, such as interacting with an element. In this case server-rendering is configured to add `defer-hydration` to all elements so that nothing will automatically hydrate. + +An app-level coordinator may implement an event delegation/buffering/replay system to detect user-events within an element and remove `defer-hydration` on demand before replaying events. + +*TODO: do we need to have an event that signals that hydration is complete before replaying events?* + +## Hydrating children + +```ts +class MyElement extends HTMLElement { + static observedAttributes = ['defer-hydration']; + + attributeChangedCallback(name, oldValue, newValue) { + if (name === 'defer-hydration' && newValue === null) { + this._hydrate(); + } + } + + _hydrate() { + // do template hydrate work + // ... + + // hydrate children + const deferredChildren = + this.shadowRoot.querySelectorAll('[defer-hydration]'); + for (const child of deferredChildren) { + child.removeAttribute('defer-hydration'); + } + } +} +``` From 1419cc3e586ce283ed69159e920e102177bbd3a0 Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Thu, 24 Jun 2021 17:44:07 -0700 Subject: [PATCH 3/5] Fix readme link --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6292767..7cbe3ff 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Check out the [Issues](https://github.com/webcomponents/community-protocols/issu ## Proposals -| Proposal | Author | Status | -|-----------------|----------------|-----------| -| [Pending Task] | Justin Fagnani | Draft | -| [Pending Task] | Justin Fagnani | Proposal | +| Proposal | Author | Status | +|-------------------|----------------|----------| +| [Pending Task] | Justin Fagnani | Draft | +| [Defer Hydration] | Justin Fagnani | Proposal | [Pending Task]: https://github.com/webcomponents/community-protocols/pull/1 [Defer Hydration]: https://github.com/webcomponents/community-protocols/pull/15 From 517045a1cb99839f0920d505241bbe27489b0304 Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Tue, 7 Nov 2023 09:37:57 -0800 Subject: [PATCH 4/5] Change status to "Proposal" --- proposals/defer-hydration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/defer-hydration.md b/proposals/defer-hydration.md index 8cacb95..88ceaa8 100644 --- a/proposals/defer-hydration.md +++ b/proposals/defer-hydration.md @@ -4,7 +4,7 @@ An open protocol for controlling hydration on the client. Author: Justin Fagnani -Status: Draft +Status: Proposal Last update: 2021-06-24 From 5623940df52522874ff500ebf7f361882526e2b0 Mon Sep 17 00:00:00 2001 From: Westbrook Johnson Date: Thu, 4 Apr 2024 11:35:58 -0400 Subject: [PATCH 5/5] Correct merge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cf10fb..8f7769e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Check out the [Issues](https://github.com/webcomponents/community-protocols/issu | [Slottable Request] | Kevin Schaaf | Proposal | [Context]: https://github.com/webcomponents/community-protocols/blob/main/proposals/context.md -[Context]: https://github.com/webcomponents/community-protocols/blob/main/proposals/defer-hydration.md +[Defer Hydration]: https://github.com/webcomponents/community-protocols/blob/main/proposals/defer-hydration.md [Pending Task]: https://github.com/webcomponents/community-protocols/blob/main/proposals/pending-task.md [Slottable Request]: https://github.com/webcomponents/community-protocols/blob/main/proposals/slottable-request.md