服务器岛
服务器岛允许你按需单独渲染动态或个性化 “islands”,而不会牺牲页面其余部分的性能。
¥Server islands allow you to on-demand render dynamic or personalized “islands” individually, without sacrificing the performance of the rest of the page.
这意味着你的访问者将更快地看到你页面的最重要部分,并允许你更积极地缓存主要内容,从而提供更快的性能。
¥This means your visitor will see the most important parts of your page sooner, and allows your main content to be more aggressively cached, providing faster performance.
服务器岛组件
标题部分 服务器岛组件¥Server island components
服务器岛是正常的服务器渲染的 Astro 组件,指示延迟渲染,直到其内容可用。
¥A server island is a normal server-rendered Astro component that is instructed to delay rendering until its contents are available.
你的页面将立即使用任何指定的 作为占位符的后备内容 渲染。然后,组件自己的内容将在客户端上获取并在可用时显示。
¥Your page will be rendered immediately with any specified fallback content as a placeholder. Then, the component’s own contents are fetched on the client and displayed when available.
使用 已安装适配器 执行延迟渲染,将 server:defer
指令 添加到页面上的任何组件以将其变成自己的岛:
¥With an adapter installed to perform the delayed rendering, add the server:defer
directive to any component on your page to turn it into its own island:
这些组件可以使用适配器执行 你通常在按需渲染页面中会用到的任何内容,例如获取内容和访问 cookie:
¥These components can do anything you normally would in an on-demand rendered page using an adapter, such as fetch content, and access cookies:
服务器岛后备内容
标题部分 服务器岛后备内容¥Server island fallback content
当在组件上使用 server:defer
属性来延迟其渲染时,你可以使用包含的名为 "fallback"
的插槽在默认加载内容中进行 “slot”。
¥When using the server:defer
attribute on a component to delay its rendering, you can “slot” in default loading content using the included named "fallback"
slot.
你的后备内容将在页面加载时与页面的其余部分一起渲染,并在可用时替换为你的组件内容。
¥Your fallback content will be rendered along with the rest of the page initially on page load and will be replaced with your component’s content when available.
要添加后备内容,请在传递给服务器岛组件的子项(其他组件或 HTML 元素)上添加 slot="fallback"
:
¥To add fallback content, add slot="fallback"
on a child (other components or HTML elements) passed to your server island component:
此后备内容可以是以下内容:
¥This fallback content can be things like:
-
通用头像,而不是用户自己的头像。
-
占位符 UI,例如自定义消息。
-
加载指示器,例如加载控件。
工作原理
标题部分 工作原理¥How it works
服务器岛实现主要发生在构建时,其中组件内容被替换为小脚本。
¥Server island implementation happens mostly at build-time where component content is swapped out for a small script.
每个标有 server:defer
的群岛都被拆分成自己的特殊路由,脚本会在运行时获取这些路由。当 Astro 构建你的站点时,它将省略组件并在其位置注入脚本,以及你用 slot="fallback"
标记的任何内容。
¥Each of the islands marked with server:defer
is split off into its own special route which the script fetches at run time. When Astro builds your site it will omit the component and inject a script in its place, and any content you’ve marked with slot="fallback"
.
当页面在浏览器中加载时,这些组件将被请求到一个特殊的端点,该端点将渲染它们并返回 HTML。这意味着用户将立即看到页面的最关键部分。在动态岛加载之前,后备内容将在短时间内可见。
¥When the page loads in the browser, these components will be requested to a special endpoint that renders them and returns the HTML. This means that users will see the most critical parts of the page instantly. Fallback content will be visible for a short amount of time before the dynamic islands are then loaded.
每个岛都独立于其他岛加载。这意味着较慢的岛不会延迟你其余个性化内容的可用性。
¥Each island is loaded independently from the rest. This means a slower island won’t delay the rest of your personalized content from being available.
此渲染模式是为可移植而构建的。它不依赖于任何服务器基础设施,因此它可以与你拥有的任何主机一起使用,从 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 you have, from a Node.js server in a Docker container to the serverless provider of your choice.
缓存
标题部分 缓存¥Caching
服务器岛的数据是通过 GET
请求检索的,在 URL 查询中将 props 作为加密字符串传递。这允许使用标准 Cache-Control
指令通过 Cache-Control
HTTP 标头 缓存数据。
¥The data for server islands is retrieved via a GET
request, passing props as an encrypted string in the URL query. This allows caching data with the Cache-Control
HTTP header using standard Cache-Control
directives.
但是,浏览器将 URL 的最大长度限制为 2048 字节 出于实际原因并避免导致拒绝服务问题。如果你的查询字符串导致你的 URL 超出此限制,Astro 将发送包含正文中所有 props 的 POST
请求。
¥However, the browser limits URLs to a maximum length of 2048 bytes for practical reasons and to avoid causing denial-of-service problems. If your query string causes your URL to exceed this limit, Astro will instead send a POST
request that contains all props in the body.
POST
请求不会被浏览器缓存,因为它们用于提交数据,并且可能导致数据完整性或安全性问题。因此,项目中任何现有的缓存逻辑都将中断。尽可能只将必要的属性传递给你的服务器岛,避免发送整个数据对象和数组以保持查询较小。
¥POST
requests are not cached by browsers because they are used to submit data, and could cause data integrity or security issues. Therefore, any existing caching logic in your project will break. Whenever possible, pass only necessary props to your server islands and avoid sending entire data objects and arrays to keep your query small.
在服务器岛中访问页面 URL
标题部分 在服务器岛中访问页面 URL¥Accessing the page URL in a server island
在大多数情况下,你的服务器岛组件可以像在普通组件中一样通过 传递 props 获取有关页面渲染的信息。
¥In most cases you, your server island component can get information about the page rendering it by passing props like in normal components.
但是,服务器岛在页面请求之外的自己的隔离上下文中运行。服务器岛组件中的 Astro.url
和 Astro.request.url
都返回一个看起来像 /_server-islands/Avatar
的 URL,而不是浏览器中当前页面的 URL。此外,如果你正在预渲染页面,你将无法访问查询参数等信息以作为 props 传递。
¥However, server islands run in their own isolated context outside of the page request. Astro.url
and Astro.request.url
in a server island component both return a URL that looks like /_server-islands/Avatar
instead of the current page’s URL in the browser. Additionally, if you are prerendering the page you will not have access to information such as query parameters in order to pass as props.
要从页面的 URL 访问信息,你可以检查 Referer 标头,该标头将包含在浏览器中加载岛的页面的地址:
¥To access information from the page’s URL, you can check the Referer header, which will contain the address of the page that is loading the island in the browser:
重复使用加密密钥
标题部分 重复使用加密密钥¥Reusing the encryption key
Astro 使用 cryptography 对传递给服务器岛的 props 进行哈希处理,以防止意外泄露机密。使用在构建期间生成的密钥对属性进行哈希处理。
¥Astro uses cryptography to hash props passed to server islands to prevent accidentally leaking secrets. The props are hashed using a key that is generated during the build.
对于大多数主机,这是透明发生的,你作为开发者无需执行任何操作。如果你在 Kubernetes 等环境中使用滚动部署,则可能会遇到前端和后端暂时不同步且密钥不匹配的问题。
¥For most hosts, this happens transparently and there is nothing that you as a developer need to do. If you are using rolling deployments in an environment such as Kubernetes, you may run into issues where the frontend and backend are temporarily out of sync and the keys don’t match.
要解决此问题,你可以使用 Astro CLI 创建一个密钥,然后在所有部署中重复使用它。这可确保每个用户的前端都在与具有正确密钥的后端通信。
¥To solve this, you can create a key with the Astro CLI and then reuse it for all of your deployments. This ensures that each user’s frontend is talking to a backend that has the right key.
使用 astro create-key
生成密钥:
¥Generate a key using astro create-key
:
这将创建一个密钥,你可以在托管环境需要的任何地方将其设置为 ASTRO_KEY
环境变量,例如在 .env
文件中:
¥This will create a key that you can set as the ASTRO_KEY
environment variable wherever your hosting environment requires, such as in a .env
file: