不使用 JavaScript 的乱序 HTML 流

1月10日 星期三 2024

让我们从一个演示开始:https://ooo.lamplightdev.workers.dev

这是一个简单的页面,渲染一个包含 10 个项目的列表。请在浏览器中启用或不启用 JavaScript 的情况下试用。有几件事值得注意:"应用程序外壳 "首先渲染--你会看到页眉和页脚,但有一个加载占位符,项目列表将在这里渲染。

一秒钟后,加载占位符被项目列表取代,但每个项目本身都有一个加载占位符。然后,项目内容按顺序渲染,取代加载占位符--你首先看到项目 5,然后是生成的其他项目。

如果查看页面源代码,就会发现 HTML 是按照发送的顺序而不是渲染的顺序显示的。

很不错吧?这可能只是一个不经意的例子,但它是一种有趣的技术,可以实现以前不使用 JavaScript 无法实现的功能。

请查看此演示的代码,或继续阅读有关其工作原理的解释。

背景介绍

流式 HTML

流式 HTML 的概念并不新鲜,即在 HTML 生成时将其从网络服务器分块发送到浏览器。在现代前端框架和单页应用(整个页面都在浏览器中生成)时代的初期,这一概念似乎退居二线,但随着钟摆重新摆向服务器端渲染和全栈框架,流式响应又开始流行起来。

与等待整个响应生成后再将其发送到浏览器相比,流式 HTML 的优势显而易见:您可以立即渲染一些内容,向用户表明正在发生一些事情;您可以在等待响应中耗时较长的部分生成的同时,提前开始下载 CSS 和 JavaScript 等资产。

在这一点上,我们一直缺乏的是一种无序流式传输 HTML 的方法,即在生成 HTML 时将其分块流式传输,而无需考虑将这些分块发送到浏览器的顺序,同时浏览器仍能按照正确的顺序呈现这些 HTML 分块,就像上面的演示一样。

现代全栈框架通过使用各种巧妙的技术实现了这一功能,但所有这些技术都需要特定框架的支持和大量的 JavaScript。对于您的用例来说,这可能没什么问题,但如果我们不使用任何 JavaScript 或框架也能实现同样的功能呢?

阴影 DOMShadow DOM 是一种与页面其他部分隔离呈现 DOM 片段的方法。虽然阴影 DOM 通常与自定义元素相关联,但它也可用于任何 HTML 标记,例如不起眼的

<div> 标签。

它还有插槽的概念,即作为门户的标签,你可以通过在父标签上指定一个

槽属性,就可以将父标签中其他地方的 HTML 内容呈现到该标签中。在这里,阴影根连接到外部

<div> 标签,而内部的

<div> 标记将呈现到阴影根中的槽中:<div> #shadowroot <header>Header</header> <main> <slotname="content"></slot> </main> <footer>Footer</footer> <divslot="content"> 此 div 将呈现到上面的槽中。神奇!</div></div>要求