Lit SSR 客户端用法
Lit SSR 为浏览器生成静态 HTML,无需任何 JavaScript 即可解析和绘制。(不支持声明式 Shadow DOM 的浏览器需要一些 JavaScript polyfill 来支持使用 Shadow DOM 编写的 Lit 组件。)对于静态内容的页面,这就足够了。但是,如果页面内容需要动态响应用户交互,则需要 JavaScript 来重新应用这种响应性。
如何在客户端重新应用响应性取决于你是渲染独立的 Lit 模板还是使用 Lit 组件。
独立 Lit 模板
Permalink to "独立 Lit 模板"Lit 模板的"水合"是指让 Lit 重新将模板表达式与其在 DOM 中应更新的节点关联起来,并添加事件监听器。为了水合 Lit 模板,@lit-labs/ssr-client 包中提供了 hydrate() 方法。在使用 render() 更新服务端渲染的容器之前,你必须首先使用与服务端渲染时相同的模板和数据对该容器调用 hydrate():
import {render} from 'lit';import {hydrate} from '@lit-labs/ssr-client';import {myTemplate} from './my-template.js';// 首次渲染前需要进行初始水合:// (必须使用与服务端渲染时相同的数据)const initialData = getInitialAppData();hydrate(myTemplate(initialData), document.body);
// 水合后,render 将高效地更新服务端渲染的 DOM:const update = (data) => render(myTemplate(data), document.body); Lit 组件
Permalink to "Lit 组件"要为 Lit 组件重新应用响应性,需要加载自定义元素定义以便它们可以升级,从而启用其生命周期回调,并且组件 Shadow Root 中的模板需要被水合。
升级可以通过加载注册自定义元素的组件模块来实现。这可以通过加载页面所有组件定义的包来完成,也可以根据更复杂的启发式策略仅在需要时加载部分定义。为了确保 LitElement Shadow Root 中的模板被水合,请加载 @lit-labs/ssr-client/lit-element-hydrate-support.js 模块,该模块为 LitElement 安装了自动水合支持,当它检测到自身是通过声明式 Shadow DOM 进行服务端渲染时会自动水合。此模块必须在加载 lit 模块之前(包括任何导入 lit 的组件模块)加载,以确保水合支持被正确安装。
当 Lit 组件在服务端渲染时,其 Shadow Root 内容会被输出在 <template shadowroot> 中,也称为声明式 Shadow Root。声明式 Shadow Root 在 HTML 解析时会自动将其内容附加到模板父元素的 Shadow Root 上,无需 JavaScript。
在所有浏览器都支持声明式 Shadow DOM 之前,有一个非常小的 polyfill 可以内联到你的页面中。这让你现在就可以在任何启用 JavaScript 的浏览器上使用 SSR,并随着该功能在其他浏览器上的推出逐步处理非 JavaScript 用例。下面描述了 template-shadowroot polyfill 的用法。
加载 @lit-labs/ssr-client/lit-element-hydrate-support.js
Permalink to "加载 @lit-labs/ssr-client/lit-element-hydrate-support.js" 需要在任何组件模块和 lit 库之前加载。
例如:
<body> <!-- 使用声明式 Shadow DOM 渲染的应用组件放置在此处。 -->
<!-- 应首先加载 ssr-client lit-element-hydrate-support。 --> <script type="module" src="/node_modules/@lit-labs/ssr-client/lit-element-hydrate-support.js"></script>
<!-- 随着组件定义的加载,你预渲染的组件将 激活并变得可交互。 --> <script src="/app-components.js"></script> </body> 如果你正在打包你的代码,请确保首先导入 @lit-labs/ssr-client/lit-element-hydrate-support.js:
// index.jsimport '@lit-labs/ssr-client/lit-element-hydrate-support.js';import './app-components.js'; 使用 template-shadowroot polyfill
Permalink to "使用 template-shadowroot polyfill" 下面的 HTML 片段包含一个可选策略,在 polyfill 加载之前隐藏 body 以防止布局偏移。
<html> <head> <!-- 在尚不支持原生声明式 Shadow DOM 的浏览器上, 在部分或全部预渲染 HTML 解析后但在声明式 Shadow DOM polyfill 生效之前可能会发生一次绘制。 此绘制是不希望的,因为它不会包含任何组件的 Shadow DOM。为了防止由此绘制导致的布局偏移, 我们使用 "dsd-pending" 属性来确保仅在确认 Shadow DOM 处于活动状态后才进行绘制。 --> <style> body[dsd-pending] { display: none; } </style> </head>
<body dsd-pending> <script> if (HTMLTemplateElement.prototype.hasOwnProperty('shadowRoot')) { // 此浏览器具有原生声明式 Shadow DOM 支持, // 因此我们可以立即允许绘制。 document.body.removeAttribute('dsd-pending'); } </script>
<!-- 使用声明式 Shadow DOM 渲染的应用组件放置在此处。 -->
<!-- 使用 type=module 脚本以便使用动态模块导入。 注意此模式在 IE11 中不可用。 --> <script type="module"> // 检查是否需要 template shadow root polyfill。 if (!HTMLTemplateElement.prototype.hasOwnProperty('shadowRoot')) { // 获取 template shadow root polyfill。 const {hydrateShadowRoots} = await import( '/node_modules/@webcomponents/template-shadowroot/template-shadowroot.js' );
// 应用 polyfill。这是一次性操作,因此在所有 // HTML 解析完成之后执行非常重要。 hydrateShadowRoots(document.body);
// 此时,不支持原生声明式 Shadow DOM 的浏览器 // 可以绘制组件的初始状态了! document.body.removeAttribute('dsd-pending'); } </script> </body></html> 此示例展示了一种将 @lit-labs/ssr-client/lit-element-hydrate-support.js 和 template-shadowroot polyfill 加载结合在一起的策略,并提供一个包含 SSR 组件的页面用于客户端水合。