Islands 架构
Astro 帮助开创和推广了一种名为 Islands Architecture 的新前端架构模式。Islands 架构的工作原理是将页面的大部分内容渲染为快速、静态的 HTML,并在页面上需要交互性或个性化(例如,图片轮播)时添加较小的 JavaScript “islands”。这避免了单片 JavaScript 负载,这些负载会降低许多其他现代 JavaScript Web 框架的响应速度。
¥Astro helped pioneer and popularize a new frontend architecture pattern called Islands Architecture. Islands architecture works by rendering the majority of your page to fast, static HTML with smaller “islands” of JavaScript added when interactivity or personalization is needed on the page (an image carousel, for example). This avoids the monolithic JavaScript payloads that slow down the responsiveness of many other, modern JavaScript web frameworks.
简短的历史
标题部分 简短的历史¥A brief history
”组件岛” 一词最初由 Etsy 的前端架构师 Katie Sylor-Miller 于 2019 年创造。随后 Preact 创建者 Jason Miller 于 2020 年 8 月 11 日在 这个帖子 中扩展并记录了这个想法。
¥The term “component island” was first coined by Etsy’s frontend architect Katie Sylor-Miller in 2019. This idea was then expanded on and documented in this post by Preact creator Jason Miller on August 11, 2020.
”群岛” 架构的总体思路看似简单:在服务器上渲染 HTML 页面,并在高度动态的区域周围注入占位符或插槽 […] 然后可以在客户端上将其 “hydrated” 到小型自包含的小部件中,重用其服务器渲染的初始 HTML。— Jason Miller,Preact 的创建者
¥The general idea of an “Islands” architecture is deceptively simple: render HTML pages on the server, and inject placeholders or slots around highly dynamic regions […] that can then be “hydrated” on the client into small self-contained widgets, reusing their server-rendered initial HTML.\ — Jason Miller, Creator of Preact
此架构模式所基于的技术也称为部分或选择性水合。
¥The technique that this architectural pattern builds on is also known as partial or selective hydration.
相比之下,大多数基于 JavaScript 的 Web 框架将整个网站合并并渲染为一个大型 JavaScript 应用(也称为单页应用或 SPA)。SPA 提供简单性和功能,但由于客户端 JavaScript 的大量使用而存在页面加载性能问题。
¥In contrast, most JavaScript-based web frameworks hydrate & render an entire website as one large JavaScript application (also known as a single-page application, or SPA). SPAs provide simplicity and power but suffer from page-load performance problems due to heavy client-side JavaScript usage.
SPA 有其一席之地,甚至是 嵌入 Astro 页面内。但是,SPA 缺乏选择性和战略性水合的原生能力,这使得它们成为当今网络上大多数项目的严厉选择。
¥SPAs have their place, even embedded inside an Astro page. But, SPAs lack the native ability to selectively and strategically hydrate, making them a heavy-handed choice for most projects on the web today.
Astro 作为第一个内置选择性水合的主流 JavaScript Web 框架而广受欢迎,它使用了 Sylor-Miller 首次提出的相同组件岛模式。从那时起,我们就在 Sylor-Miller 的原创作品的基础上进行了扩展和发展,这有助于激发类似的组件岛方法来动态服务器渲染内容。
¥Astro became popular as the first mainstream JavaScript web framework with selective hydration built-in, using that same component islands pattern first coined by Sylor-Miller. We’ve since expanded and evolved on Sylor-Miller’s original work, which helped to inspire a similar component island approach to dynamically server-rendered content.
什么是群岛?
标题部分 什么是群岛?¥What is an island?
在 Astro 中,群岛是 HTML 静态页面上的增强型 UI 组件。
¥In Astro, an island is an enhanced UI component on an otherwise static page of HTML.
客户端岛 是一个交互式 JavaScript UI 组件,它与页面的其余部分分开进行水化,而 服务器岛 是一个 UI 组件,它将其动态内容与页面的其余部分分开进行服务器渲染。
¥A client island is an interactive JavaScript UI component that is hydrated separately from the rest of the page, while a server island is a UI component that server-renders its dynamic content separately from the rest of the page.
为了优化页面加载,两个群岛都以每个组件为基础独立运行昂贵或较慢的进程。
¥Both islands run expensive or slower processes independently, on a per-component basis, for optimized page loads.
Island 组件
标题部分 Island 组件¥Island components
Astro 组件是页面模板的构建块。它们渲染为静态 HTML,没有客户端运行时。
¥Astro components are the building blocks of your page template. They render to static HTML with no client-side runtime.
将客户端岛想象成一个交互式小部件,漂浮在一片静态、轻量级、服务器渲染的 HTML 海洋中。可以为个性化或动态服务器渲染元素添加服务器岛,例如登录访问者的个人资料图片。
¥Think of a client island as an interactive widget floating in a sea of otherwise static, lightweight, server-rendered HTML. Server islands can be added for personalized or dynamic server-rendered elements, such as a logged in visitor’s profile picture.
静态内容,如文本、图片等。
¥Static content like text, images, etc.
Source: Islands Architecture: Jason Miller
一个孤岛始终与页面上的其他孤岛隔离运行,并且一个页面上可以存在多个孤岛。即使客户端岛在不同的组件上下文中运行,它们仍然可以共享状态并相互通信。
¥An island always runs in isolation from other islands on the page, and multiple islands can exist on a page. Client islands can still share state and communicate with each other, even though they run in different component contexts.
这种灵活性使 Astro 能够支持多种 UI 框架,例如 React、Preact、Svelte、Vue 和 SolidJS。因为它们是独立的,所以你甚至可以在每个页面上混合使用多个框架。
¥This flexibility allows Astro to support multiple UI frameworks like React, Preact, Svelte, Vue, and SolidJS. Because they are independent, you can even mix several frameworks on each page.
客户端岛
标题部分 客户端岛¥Client Islands
默认情况下,Astro 会自动将每个 UI 组件渲染为 HTML 和 CSS,自动删除所有客户端 JavaScript。
¥By default, Astro will automatically render every UI component to just HTML & CSS, stripping out all client-side JavaScript automatically.
这听起来可能很严格,但这种行为默认情况下可以保持 Astro 网站的快速运行,并防止开发者意外发送不必要或不需要的 JavaScript,从而降低其网站速度。
¥This may sound strict, but this behavior is what keeps Astro websites fast by default and protects developers from accidentally sending unnecessary or unwanted JavaScript that might slow down their website.
将任何静态 UI 组件变成交互式岛只需要 client:*
指令。然后,Astro 会自动构建并打包你的客户端 JavaScript 以优化性能。
¥Turning any static UI component into an interactive island requires only a client:*
directive. Astro then automatically builds and bundles your client-side JavaScript for optimized performance.
对于孤岛,仅为使用 client:*
指令标记的显式交互组件加载客户端 JavaScript。
¥With islands, client-side JavaScript is only loaded for the explicit interactive components that you mark using client:*
directives.
而且由于交互是在组件级别配置的,因此你可以根据每个组件的使用情况处理不同的加载优先级。例如,client:idle
告诉组件在浏览器空闲时加载,而 client:visible
告诉组件仅在进入视口时加载。
¥And because interaction is configured at the component-level, you can handle different loading priorities for each component based on its usage. For example, client:idle
tells a component to load when the browser becomes idle, and client:visible
tells a component to load only once it enters the viewport.
Benefits of client islands
使用 Astro 群岛构建的最明显的好处是性能:你网站的大部分内容都会转换为快速、静态的 HTML,并且仅为需要它的各个组件加载 JavaScript。JavaScript 是按字节加载最慢的资源之一,因此每个字节都很重要。
¥The most obvious benefit of building with Astro Islands is performance: the majority of your website is converted to fast, static HTML and JavaScript is only loaded for the individual components that need it. JavaScript is one of the slowest assets that you can load per-byte, so every byte counts.
另一个好处是并行加载。在上面的示例图中,低优先级 “图片轮播” 岛不需要阻挡高优先级 “header” 岛。两者并行加载并独立进行水合,这意味着标题立即变得可交互,而无需等待页面下方较重的轮播。
¥Another benefit is parallel loading. In the example illustration above, the low-priority “image carousel” island doesn’t need to block the high-priority “header” island. The two load in parallel and hydrate in isolation, meaning that the header becomes interactive immediately without having to wait for the heavier carousel lower down the page.
更好的是,你可以准确地告诉 Astro 如何以及何时渲染每个组件。如果该图片轮播的加载成本确实很高,你可以附加一个特殊的 客户指令,告诉 Astro 仅当轮播在页面上可见时才加载该轮播。如果用户从未看到它,则它永远不会加载。
¥Even better, you can tell Astro exactly how and when to render each component. If that image carousel is really expensive to load, you can attach a special client directive that tells Astro to only load the carousel when it becomes visible on the page. If the user never sees it, it never loads.
在 Astro 中,作为开发者,你需要明确告诉 Astro 页面上的哪些组件也需要在浏览器中运行。Astro 只会水化页面上所需的内容,并将网站的其余部分保留为静态 HTML。
¥In Astro, it’s up to you as the developer to explicitly tell Astro which components on the page need to also run in the browser. Astro will only hydrate exactly what’s needed on the page and leave the rest of your site as static HTML.
客户端岛是 Astro 默认快速性能故事的秘密!
¥Client islands are the secret to Astro’s fast-by-default performance story!
服务器岛
标题部分 服务器岛¥Server islands
服务器岛是一种将昂贵或缓慢的服务器端代码移出主渲染过程的方法,可轻松组合高性能静态 HTML 和动态服务器生成的组件。
¥Server islands are a way to move expensive or slow server-side code out of the way of the main rendering process, making it easy to combine high-performance static HTML and dynamic server-generated components.
将 server:defer
指令 添加到你页面上的任何 Astro 组件,将其变成自己的服务器岛:
¥Add the server:defer
directive to any Astro component on your page to turn it into its own server island:
这会将你的页面分解为较小的服务器渲染内容区域,每个区域都并行加载。
¥This breaks up your page with smaller areas of server-rendered content that each load in parallel.
你的页面的主要内容可以立即使用占位符内容渲染,例如通用头像,直到你的群岛自己的内容可用。使用服务器岛,拥有个性化内容的小组件不会延迟静态页面的渲染。
¥Your page’s main content can be rendered immediately with placeholder content, such as a generic avatar until your island’s own content is available. With server islands, having small components of personalized content does not delay the rendering of an otherwise static page.
此渲染模式是为可移植而构建的。它不依赖于任何服务器基础设施,因此它可以与任何主机一起使用,从 Docker 容器中的 Node.js 服务器到你选择的无服务器提供商。
¥This rendering pattern was built to be portable. It does not depend on any server infrastructure so it will work with any host, from a Node.js server in a Docker container to the serverless provider of your choice.
Benefits of server islands
服务器岛的一个好处是能够动态渲染页面中动态程度更高的部分。这允许更积极地缓存外壳和主要内容,从而提供更快的性能。
¥One benefit of server islands is the ability to render the more highly dynamic parts of your page on the fly. This allows the outer shell and main content to be more aggressively cached, providing faster performance.
另一个好处是提供出色的访客体验。服务器岛经过优化,加载速度快,通常甚至在浏览器绘制页面之前。但在群岛渲染所需的短暂时间内,你可以显示自定义后备内容并防止任何布局偏移。
¥Another benefit is providing a great visitor experience. Server islands are optimized and load quickly, often even before the browser has even painted the page. But in the short time it takes for your islands to render, you can display custom fallback content and prevent any layout shift.
受益于 Astro 服务器岛的站点示例是电子商务店面。虽然产品页面的主要内容很少更改,但这些页面通常包含一些动态部分:
¥An example of a site that benefits from Astro’s server islands is an e-commerce storefront. Although the main content of product pages change infrequently, these pages typically have some dynamic pieces:
-
标题中的用户头像。
-
产品的特别优惠和销售。
-
用户评论。
使用这些元素的服务器岛,你的访问者将立即看到页面的最重要部分,即你的产品。通用头像、加载旋转器和商店公告可以显示为后备内容,直到个性化部分可用。
¥Using server islands for these elements, your visitor will see the most important part of the page, your product, immediately. Generic avatars, loading spinners, and store announcements can be displayed as fallback content until the personalized parts are available.