Skip to content
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

Adds support for FASTElement hydration #6977

Merged

Conversation

prabhujayapal
Copy link
Contributor

@prabhujayapal prabhujayapal commented Jun 6, 2024

Adds support for FASTElement hydration

Pull Request

📖 Description

This PR consolidates Server-Side Rendering (SSR) related changes made by @nicholasrice from a Microsoft internal fork. Below is the commit description from the original PR.


This PR enables hydration of FAST custom elements from HTML emitted by SSR processes.

This PR has three core areas:

  1. I've added a SSR example application to /examples to aid in debugging. This code was ported from external FAST.
  2. I've updated fast-ssr to accept a emitHydratableMarkup attribute. Configuring this option causes markers to be emitted during template rendering. These markers manifest either as element attributes (for attribute bindings / directives) and HTML comments (for content bindings / directives). These markers are used by fast-element to identify which elements belong to which views and bindings.
  3. fast-element has been updated to support hydrating views, details below.

fast-element changes:

  1. Updated HydratableElementController to invoke hydrate on it's template during connection, also refactored ElementController base class to allow better direct extension by making private properties protected.
  2. Added a HydrationView class. An instance of this class represents a region of DOM created by a template during the SSR process. When this class binds for the first time, it walks the DOM tree between it's first and last nodes looking for binding markers emitted during fast-ssr rendering. When it finds binding markers, it associates the template binding to that DOM location. After all the nodes have been walked and the bindings targeted, behaviors for those bindings are created and bound, hooking up observable behavior.
  3. Updated bindings and directives to handle hydration scenarios. Unfortunately, I was not able to identify a good way to separate the hydration behavior from the CSR binding behavior without implementing a large amount of code duplication. Instead, I added a lightweight isHydratable() test to determine whether bindings should go through hydration flows. Bindings and directives were then updated to not affect DOM during hydration flows.

🎫 Issues

👩‍💻 Reviewer Notes

📑 Test Plan

✅ Checklist

General

  • I have included a change request file using $ yarn change
  • I have added tests for my changes.
  • I have tested my changes.
  • I have updated the project documentation to reflect my changes.
  • I have read the CONTRIBUTING documentation and followed the standards for this project.

⏭ Next Steps

@nicholasrice
Copy link
Contributor

Thanks for bringing this over @prabhujayapal! Give me a few days and I can get a review on it.

Copy link
Contributor

@nicholasrice nicholasrice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall it looks good. I do recommend implementing #6760 to augment this PR. I recall hydration behavior being confusing for component authors because connectedCallback() is invoked by the browser regardless of hydration state, and subclasses will always get that callback invoked prior to FASTElement base-class. Authors tend to do work in connectedCallback that they actually want to do once hydrated in hydration scenarios, and the linked issue describes a way to align both scenarios.

Original PR was made in a fork by `nicholasrice`. Below is the commit description from the original PR.

This PR enables hydration of FAST custom elements from HTML emitted by SSR processes.

This PR has three core areas:

I've added a SSR example application to /examples to aid in debugging. This code was ported from external FAST.
I've updated fast-ssr to accept a emitHydratableMarkup attribute. Configuring this option causes markers to be emitted during template rendering. These markers manifest either as element attributes (for attribute bindings / directives) and HTML comments (for content bindings / directives). These markers are used by fast-element to identify which elements belong to which views and bindings.
fast-element has been updated to support hydrating views, details below.
fast-element changes:

Updated HydratableElementController to invoke hydrate on it's template during connection, also refactored ElementController base class to allow better direct extension by making private properties protected.
Added a HydrationView class. An instance of this class represents a region of DOM created by a template during the SSR process. When this class binds for the first time, it walks the DOM tree between it's first and last nodes looking for binding markers emitted during fast-ssr rendering. When it finds binding markers, it associates the template binding to that DOM location. After all the nodes have been walked and the bindings targeted, behaviors for those bindings are created and bound, hooking up observable behavior.
Updated bindings and directives to handle hydration scenarios. Unfortunately, I was not able to identify a good way to separate the hydration beahvior from the CSR binding behavior without implementing a large amount of code duplication. Instead, I added a lightweight isHydratable() test to determine whether bindings should go through hydration flows. Bindings and directives were then updated to not affect DOM during hydration flows.
@janechu janechu force-pushed the users/prjayapa/add-ssr-hydration branch from 8906270 to e285630 Compare July 5, 2024 17:52
@janechu janechu force-pushed the users/prjayapa/add-ssr-hydration branch from e285630 to 1c4ee83 Compare July 5, 2024 18:15
@janechu janechu merged commit 882eded into microsoft:master Jul 5, 2024
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants