自Astro 1.0首次发布以来,开发者必须在生成静态 (SSG) 或服务器 (SSR) 输出之间做出选择。静态网站通过预构建页面提供卓越的性能。服务器利用其动态能力按需生成HTML,为每个请求提供独有的内容。
直到现在,这仍然是一个非此即彼的决定——是完全静态的,还是应该部署一个服务器?
Astro 2.0通过混合渲染解锁了两全其美的优势。您可以为网站的每个页面选择静态页面的性能或服务器渲染的完全灵活性。
在这篇文章中,我们将通过探索Astro 2.0中可能实现的几项新功能和性能改进,来探讨混合渲染的工作原理。
Astro 的构建过程是如何工作的?
Astro 的构建过程分多个阶段进行,首先是由Vite生成的服务端 JavaScript 包。简单来说,此包的输出包括:
- 用于渲染 HTML 的服务端 JavaScript
- 一个客户端清单,它使用静态分析来收集客户端交互所需的所有组件
- 用于客户端的 CSS 和其他资源
接下来,Astro 使用客户端清单启动第二个构建过程,该过程打包优化的客户端 JavaScript。
如果您的配置output是static,Astro 将执行服务端 JavaScript 并将输出写入.html文件。然后,服务端 JavaScript 会被丢弃。
如果您的配置output是server,Astro 会将服务端 JavaScript 传递给adapter进行进一步处理。适配器确保您的服务端 JavaScript 与特定托管提供商的 JavaScript 运行时兼容。请注意,在这种情况下,最终输出不是一组.html文件,而是渲染 HTML 所需的 JavaScript 代码。
不幸的是,这种设置非常僵化,不允许在同一个项目中混合静态路由和动态路由。我们真正需要的是一个能够并行启用这两种模式的过程。
混合渲染是如何工作的?
在 Astro 2.0 中,我们改进了astro build构建流程以处理混合渲染。在初始打包过程中,一个新的静态分析步骤会确定哪些页面应该被预渲染。这使我们能够根据页面何时渲染,将其路由拆分为单独的块。
与最初的static过程非常相似,预渲染的块会被执行,输出会写入.html文件。然后,该块会被丢弃。
与最初的server过程非常相似,服务器块会被传递给一个adapter进行进一步处理。最终,它将根据您的适配器部署为 Serverless 或 Edge 函数。
为什么要使用静态分析?
静态分析是一种无需实际执行源代码即可分析源代码的技术。Astro 在许多地方都依赖这种方法,但在构建过程中尤其关键。出于性能原因,Astro 必须能够在不执行页面源代码的情况下对其进行分类。对于小型项目,执行可能不是问题,但规模化后很快就会成为瓶颈。
混合渲染是专门为静态分析而设计的,尽管我们确实考虑过替代的 API。Astro 的构建过程能够检查是否存在export const prerender = true语句来确定哪些页面应该被预渲染。为了高效地完成此操作,我们依赖于出色的es-module-lexer库,该库也在 Node 内部使用。
---// This route should be generated at build time!export const prerender = true
const text = await fetch("https://example.com/").then((res) => res.text())---
<article set:html={text} />混合渲染的用例
混合渲染解锁了全新的一系列可能用例,但我们想重点介绍一些我们特别兴奋的用例。
用例:提高热门页面的渲染性能
考虑一个使用 Astro 构建的中小型电子商务网站,其中包含数千种不同的产品和变体。如果您使用静态网站生成,那么每次这些产品发生变化或缺货时,您都将被迫重建网站。
这类项目需要服务端渲染,这样您的产品页面就可以在每个请求时新鲜生成。但现在我们遇到了一个新问题:您的主页不再是静态的。加载性能对于促进销售仍然至关重要,而您的主页并没有任何动态内容需要它在每个请求时都重新构建。
混合渲染通过提前将主页渲染为静态 HTML 来解决我们的性能问题,同时保持网站其余部分按需渲染。
用例:为现有静态网站添加 API
随着您的静态网站不断增长,您可能会发现需要托管一个公共 API。从历史上看,向静态网站添加 API 需要主机特定的配置,但在 Astro 2.0 中,我们可以添加服务器端点(API 路由)而无需牺牲静态页面的性能。
事实上,服务器端点可以通过我们的集成 API的injectRoute钩子自动添加。我们很高兴能通过这些新原语培育一个强大的第三方集成生态系统!
用例:提升大型网站的构建性能
静态生成难以扩展到数千个页面,因为每个页面都必须在构建过程中渲染。服务端渲染将页面渲染推迟到请求时,从而消除了构建过程中的潜在瓶颈。
当有数百个路由由getStaticPaths生成时,服务端渲染可以带来显著的性能提升。在我们的内部测试中,通过将动态路由切换到服务端渲染,我们看到构建时间提升了高达 30%。
开始使用混合渲染
混合渲染现已在 Astro 2.0 中可用!您可以前往我们的服务端渲染指南了解更多 Astro 的 SSR 功能。Astro 的官方适配器也已更新以支持混合渲染,因此请务必安装您的适配器的最新版本。
为庆祝发布,我们的朋友SST刚刚推出了astro-sst,他们官方的 Astro AWS 适配器。查看他们的发布视频和演练以了解更多并开始使用 AWS + SST。
我们欢迎您的反馈!在预渲染 API RFC期间,我们收集了一些很棒的意见,并邀请您使用我们新的公开路线图或Discord 社区提出未来的想法。