原文:https://www.patterns.dev/vanilla/islands-architecture
标题:Import On Interaction
作者:patterns.dev
PS:文章来自最近很火的良心网站Patterns.dev,站点文章不单单教你写代码,更是教你学习设计模式等。
tl;dr:孤岛架构鼓励在服务器渲染的网页中进行小而集中的交互。岛屿的输出是逐步增强的HTML,对增强发生的方式更加具体。与单个应用程序控制整个页面渲染不同,其存在多个入口点。这些交互的“岛屿”的脚本可以独立地传递和激活,允许页面的其余部分只是静态HTML。
加载和处理过多的 JavaScript 可能会影响性能。然而,即使在主要是静态网站中,一定程度的互动和 JavaScript 通常是必需的。我们已经讨论了静态渲染的各种变体,使你能够构建试图达到以下平衡的应用程序:
SSR 的核心原则是在服务器端渲染 HTML,并附带必要的 JavaScript 在客户端重新激活它。重新激活是指在服务器端渲染后,在客户端重新生成 UI 组件状态的过程。由于重新激活会带来成本,因此每个 SSR 的变体都试图优化重新激活的过程。这主要通过对关键组件进行部分重新激活或在组件渲染时进行流式传输来实现。然而,以上技术最终传输的 JavaScript 净量保持不变。
“Islands” 架构这个术语是由 Katie Sylor-Miller 和 Jason Miller 推广,用来描述一种旨在通过“岛屿”式的互动来减少通过的 JavaScript 量的范式。岛屿是一种基于组件的架构,建议以静态和动态岛屿的方式对页面进行分隔的视图。页面的静态区域是纯非互动的 HTML,不需要重新激活。动态区域是 HTML 和脚本的组合,在渲染后能够重新激活自己。
让我们进一步探讨岛屿建筑的细节,以及目前可以实现它的不同选择。
大多数页面都是静态和动态内容的组合。通常,页面由静态内容和可以被隔离的交互式区域组成。例如:
静态内容是无状态的,不会触发事件,并且在呈现后不需要再次激活。呈现后,动态内容(按钮、筛选器、搜索栏)必须重新连接到其事件。DOM 必须在客户端重新生成(虚拟 DOM)。这种重新生成、激活和事件处理功能会导致发送到客户端的 JavaScript。
岛屿架构有助于服务器端呈现包含所有静态内容的页面。但在这种情况下,呈现的 HTML 将包含动态内容的占位符。动态内容的占位符包含独立的组件小部件。每个小部件类似于一个应用程序,结合了服务器端呈现的输出和用于在客户端激活应用程序的 JavaScript。
在渐进式激活中,页面的激活架构是自上而下的。页面控制着个别组件的调度和激活。在岛屿架构中,每个组件都有自己的激活脚本,可以异步执行,与页面上的任何其他脚本无关。一个组件中的性能问题不应影响其他组件。
孤岛架构借鉴了不同来源的概念,旨在将它们最佳地结合起来。基于模板的静态站点生成器(例如 Jekyll 和 Hugo)支持将静态组件渲染到页面。大多数现代 JavaScript 框架还支持同构渲染,它允许您使用相同的代码在服务器和客户端上渲染元素。
ason 的帖子建议使用 requestIdleCallback()
来实现组件水合的调度方法。组件级部分水合的静态同构渲染和调度可以构建到框架中以支持岛屿架构。因此,该框架应该
可以使用接下来讨论的开箱即用选项之一来实现此目的。
请注意,Marko 和 Eleventy 早于 Jason 提供的 Islands 定义,但包含支持它所需的一些功能。然而,Astro 是基于定义构建的,并且本质上支持 Islands 架构。在下一节中,我们将演示如何使用 Astro 作为前面讨论的简单博客页面示例。
以下是我们使用 Astro 实现的示例博客页面。页面 SamplePost 导入一个交互式组件 SocialButtons。此组件通过标记包含在 HTML 中的所需位置。
---
// Component Imports
import { SocialButtons } from '../../components/SocialButtons.js';
---
<html lang="en">
<head>
<link rel="stylesheet" href="/blog.css" />
</head>
<body>
<div class="layout">
<article class="content">
<section class="intro">
<h1 class="title">Post title (static)</h1>
<br/>
<p>Post sub-title (static)</p>
</section>
<section class="intro">
<p>This is the post content with images that is rendered by the server.</p>
<Image src="https://source.unsplash.com/user/c_v_r/200x200" />
<p>The next section contains the interactive social buttons component which includes its script.</p>
</section>
<section class="social">
<div>
<SocialButtons client:visible></SocialButtons>
</div>
</section>
</article>
</div>
</body>
</html>
import { useState } from "preact/hooks";
export function SocialButtons() {
const [count, setCount] = useState(0);
const add = () => setCount((i) => i + 1);
const subtract = () => setCount((i) => i - 1);
return (
<>
<div>{count} people liked this post</div>
<div align="right">
<Image src="/like.png" width="32" height="32" onclick={add}></img>
<Image src="/unlike.png" width="32" height="32" onclick={subtract}></img>
</div>
</>
);
}
SocialButtons
组件是一个 Preact 组件,其中包含其 HTML 和相应的事件处理程序。
该组件在运行时嵌入到页面中,并在客户端冻结,以便单击事件根据需要运行。
Astro 允许 HTML、CSS 和脚本之间完全分离,并鼓励基于组件的设计。使用此框架可以轻松安装和开始构建网站。
Islands 体系结构结合了来自不同渲染技术(如服务器端渲染、静态站点生成和部分冻结)的想法。实施岛屿的一些潜在好处如下。
将 Astro 与为 Next.js 和 Nuxt.js 创建的文档网站进行比较,发现 JavaScript 代码减少了 83%。其他用户也报告了 Astro 的性能改进。
图片提供:https://divriots.com/blog/our-experience-with-astro/
尽管有这些优势,但这个概念仍处于起步阶段。有限的支持导致了一些缺点。
Islands 架构概念相对较新,但由于其性能优势,可能会加快速度。它强调了使用 SSR 来呈现静态内容,同时通过动态组件支持交互性,同时将对页面性能的影响降至最低。我们希望未来在这个领域看到更多的参与者,并有更广泛的实施选项可供选择。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。