Astro 4.12 现已发布!此版本包含服务器岛屿的首次实验性发布,这是我们整合高性能静态 HTML 和动态服务器生成组件的新解决方案。此外还包括分页和语法高亮方面的改进。
此版本包括以下亮点
要升级现有项目,请使用自动化的 @astrojs/upgrade
CLI 工具。或者,通过运行包管理器的升级命令来手动升级
# Recommended:npx @astrojs/upgrade
# Manual:npm install astro@latestpnpm upgrade astro --latestyarn upgrade astro --latest
实验性功能:服务器岛屿
2021年,Astro 将“岛屿架构”理念引入主流,允许您创建交互式客户端组件的“岛屿”,同时页面的大部分内容是静态生成的。
通过服务器岛屿,我们将相同的架构扩展到了服务器端。服务器岛屿使得高性能静态 HTML 和动态服务器生成组件的结合变得容易。
在任何给定的网页中,您可能会有以下内容:
- 完全静态且永不改变的内容。
- 由数据库动态支持,变化不频繁,但比您部署的频率更高。
- 个性化内容,为个人用户量身定制。
目前,您必须为所有这些类型的内容选择一种缓存策略,如果页面是登录体验,通常意味着根本没有缓存。现在,有了服务器岛屿,您可以鱼与熊掌兼得。

服务器岛屿用于您最动态的内容;例如用户的头像、购物车和产品评论等个性化内容。当这些组件被延迟加载时,您可以更积极地缓存页面本身。
这意味着无论用户是否登录,都将立即看到页面的最关键部分,因为它们正在边缘 CDN 上缓存。回退内容将在动态岛屿加载之前短暂可见。
每个岛屿都是独立于其他岛屿加载的;这意味着一个较慢的岛屿,例如连接到旧版后端的岛屿,不会延迟其他个性化内容的显示和交互。
性能
为了验证这一想法的可行性,我们构建了 server-islands.com。这个演示受到了 Next.js 部分预渲染演示的启发,并重新设计以符合 Astro 的风格。服务器岛屿与部分预渲染 (PPR) 有很多共同之处,尤其是在提高页面可缓存性这一目标上。
衡量指标 | partialprerendering.com | server-islands.com |
---|---|---|
TTFB首字节时间 | 0.838秒 | 0.766秒 |
FCP首次内容绘制 | 1.740秒 | 1.251秒 |
LCP最大内容绘制 | 1.740秒 | 1.405秒 |
TBT总阻塞时间 | 0.093秒 | 0.018秒 |
来源 | WebPageTest | WebPageTest |
server-islands.com 在重复运行中表现出持续更快的速度;它在最大内容绘制(Largest Contentful Paint)方面快了20%,这是 Google 的三大核心网页指标之一,影响着用户体验和搜索引擎优化。
服务器岛屿不像 PPR 那样在服务器上启动对源站的请求,而是从浏览器端执行。这意味着虽然服务器岛屿可以更早地绘制内容,但它们可能比 PPR 更晚完成。
服务器岛屿和 PPR 都最适用于主页内容可以进行边缘缓存的网站。它们适用于电子商务网站,但可能不适合用于社交网络动态。由于页面经过边缘缓存,对岛屿请求的等待时间是最小的。
最终,我们相信这种权衡是 Astro 用户在用户体验和通过核心网页指标方面获得最佳整体性能的方式,并且无需任何特殊的后端基础设施或支持即可开始使用。
可移植性
我们在构建服务器岛屿时考虑到了可移植性。它不依赖于任何服务器基础设施,因此可以与您拥有的任何主机配合使用,无论是 Docker 容器中的 Node.js 服务器,还是您选择的无服务器提供商。
我们的实现主要发生在构建时,组件内容会被替换为一个小脚本,其大小几乎可以发布一条推文。
每个标记有 server:defer
的岛屿都被拆分成独立的特殊路由,脚本在运行时会抓取它们。权衡之处在于,如果岛屿依赖于边缘处理,它可能无法获得先发渲染优势,但我们认为迄今为止所采取的更简单方法在性能数据上更具优势。
试用服务器岛屿
我们仍在努力完善该功能,但您今天就可以通过在 Astro 4.12 中启用该功能来试用 Astro 服务器岛屿。
import { defineConfig } from 'astro/config';import netlify from '@astrojs/netlify';
export default defineConfig({ output: 'hybrid', adapter: netlify(),
experimental: { serverIslands: true, },})
顾名思义,服务器岛屿在服务器上运行,因此您需要使用 'server'
或 'hybrid'
输出模式。启用此功能后,您可以在任何组件上使用 server:defer
指令来使用它们。
<Avatar server:defer> <GenericUserImage slot="fallback" /></Avatar>
当 Astro 构建您的站点时,它将省略该组件并在其位置注入一个脚本,此外还包括您标记为 slot="fallback"
的内容。当页面在浏览器中加载时,这些组件及其传递的任何 props 都将请求到一个特殊的端点,该端点会渲染它们并返回 HTML。
服务器岛屿是普通的 Astro 组件,可以使用 Astro 中您期望的任何功能,例如中间件、插槽和 client:
岛屿。
参与其中
服务器岛屿有一个活跃的 RFC。我们仍在敲定细节和功能;例如,我们可能会添加加密属性。请在 4.12 版本中试用,并告诉我们您的想法。
在分页数据中添加了 first
和 last
URL
paginate() 辅助函数现在在分页数据中返回 first
和 last
属性。这些属性分别包含第一页和最后一页的 URL。感谢 @tsawada 贡献此功能!
添加了对 Shiki 的 defaultColor
选项的支持
defaultColor
选项允许您覆盖主题内联样式的值,仅添加 CSS 变量,从而在应用多个颜色主题时提供更大的灵活性。此选项可以在您的 Shiki 配置中进行配置以应用于整个站点,也可以传递给 Astro 内置的 <Code>
组件来样式化单个代码块。感谢 @madcampos 贡献此功能!
新的 inferRemoteSize
函数
在 Astro 4.4 中,我们为 Image 和 Picture 组件以及 getImage()
添加了一个新属性,用于自动推断远程图片的大小。感谢 @itsmatteomanf,此版本现在包含一个新函数 inferRemoteSize()
,允许您独立于这些组件或 getImage()
获取远程图片的大小。
如果您使用图片宽度生成不同的密度,或者您需要图片尺寸用于样式目的,这会很有用。
---import { inferRemoteSize, Image } from 'astro:assets';
const { width, height } = await inferRemoteSize('https://...');---
<Image src={"https://..."} width={width / 2} height={height} densities={[1.5, 2]} />
更多内容
一如既往,Astro 4.12 包含了更多本文未提及的 bug 修复和小型改进!查看完整的 发布说明以了解更多信息。
特别感谢 @sarah11918、@Fryuni、@ARipeAppleByYoursTruly 以及所有为本次发布做出贡献的人员。