,就在上周,Astro 团队发布了 1.0 的正式版本。,从年初我就开始关注这个项目了,但当时只是学习了一下仓库的工程化搭建相关的东西 (changesets 自动发包之类),并没有深入了解它本身的功能。借着正式发版的机会,这几天熟悉了一下 Astro 1.0,发现了很多有意思的地方,下文会分别从团队背景、框架定位和核心优势几个维度给大家展开介绍,最后也会推荐一些学习资料。,在正式介绍 Astro 之前,先给大家聊一聊相关的背景。Astro 的作者是 Fred K. Schott,没错,就是那个开发 Snowpack 的老哥,可以说是 Unbundle 构建工具的祖师爷:,
,但无奈的是 Vite 发展势头实在太猛,而 Snowpack 渐渐日薄西山,他本人也写了文章发出下面的感慨:,
,大意就是 Snowpack 前途渺茫,用户越来越少,感觉要做到头了啦,而 Vite 发展的非常好,那后面开发的 Astro 就基于 Vite 来做吧。现在连 Snowpack 的官网都表示弃坑了,主动给 Vite 引流:,
,当然,除了 Snowpack,Fred K. Schott 的团队(叫Pika)还做了一件比较知名的产品: Skypack,即 NPM 包的 ESM CDN 服务:,
,不幸的是,Skypack 也很长时间(一年多)没有维护了,可以看出团队也不再想继续投入这个项目了,个人感觉主要有两个原因:,在近些年的时间里,Fred K. Schott 团队一直将重心放在了新项目 Astro 上面,经过 16 个月的打磨, Astro 在全球拥有了 30000 多个用户,被 Google、Netlify 等大公司使用,Github 的 star 已经达到 15k +。,值得一提的是,Fred K. Schott 为了这个项目专门成立了一个创业公司: The Astro Technology Company,并且已经融到了 700 万美刀的种子轮投资,打算一直以开源的方式发展下去。相比于一些知名开源项目的赞助收入,如 Webpack[1] 22 w 刀/年、Babel[2] 30 w 刀/年,Astro 在经济方面有如鱼得水的优势。,接下来聊一聊 Astro 框架的定位,是像 Vue、React 这样的底层渲染框架,还是像 Next.js 这种上层的研发框架?,这一点其实挺困扰初学者的,因为 Astro 既自创了类似于.vue、.jsx文件的 .astro 语法,又提供了像 Next.js 里面各种运行时的能力,比如约定式路由、构建优化、SSR 等等。,但实际上它给自己的定位非常清晰,即 content-focused 应用开发框架,换句话说,就是重内容、轻交互场景下的上层研发框架,比如大多数电商网站、文档站、博客站、证券网站等等。,你可以将 Astro 理解为一个垂直场景下的Next.js,但它可以在它适用的领域里面可以胜过其它所有竞品(如Next.js、Remix、Vuepress 等),这是它能够做起来的重要原因。接下来,我们就来看看 Astro 的优势在于哪些地方。,Astro 的主要优势包括如下几点:,在如上的几个优点中,我们来重点说一说 Astro 的 Islands 架构,因为这是它高性能最主要的原因。,Islands 架构模型早在 2019 年就被提出来了,并在 2011 年被 Preact 作者Json Miller 在Islnads Architecture[3] 一文中得到推广。这个模型主要用于 SSR (也包括 SSG) 应用,我们知道,在传统的 SSR 应用中,服务端会给浏览器响应完整的 HTML 内容,并在 HTML 中注入一段完整的 JS 脚本用于完成事件的绑定,也就是完成 hydration (注水) 的过程。当注水的过程完成之后,页面也才能真正地能够进行交互。,那么当应用的体积逐渐增大时,需要在客户端执行的 JS 脚本也会越来越多,这也意味着 TTI(可交互时间) 指标越来越高:,
,为了解决这个问题,Islands 架构将页面拆分为各自独立的组件,包含静态组件和可交互组件,如下图的例子所示:,
,可以清楚的看到,一个页面中只有部分的组件交互,那么对于这些可交互的组件,我们可以并行地执行 hydration 过程,因为组件之间是互相独立的。,而对于静态组件,即不可交互的组件,我们可以让其不参与 hydration 过程,直接复用服务端下发的 HTML 内容。,可交互的组件就犹如整个页面中的孤岛(Island),因此这种模式叫做 Islands 架构。,相比于传统 SSR 中的全量 hydration,Islands 模式可以实现局部(partial) hydration,从而优化 JS 的体积,减少网络传输的成本和 JS 运行时的开销。,在 Astro 中,默认所有的组件都是静态组件,比如:,值得注意的是,这种写法不会在浏览器添加任何的 JS 代码。但有时我们需要在组件中绑定一些交互事件,那么这时就需要激活孤岛组件了,在 Astro 如何来激活呢?其实很简单,在使用组件时加上client:load指令即可:,如此一来,Astro 会给浏览器传输一部分 JS 代码供这个组件完成 hydration,以便后续的交互。,读到这里,你可能会说了,相比于其它的业界方案,Astro 到底优势在哪里呢?我们不妨来盘点一下。,首先是大名鼎鼎的 Next.js,我们知道 Next.js 是一个非常经典的 React SSR 框架,也是使用传统的 SSR/SSG 技术,可以适用于几乎所有的 Web 开发场景。而 Astro 在其适用的content-focused场景下,性能会明显高于 Next.js,以下是两个真实的迁移案例:,
,可以看到,Astro 相比 Next.js 可以大幅度减少 JS 代码的体积(90% 以上),同时页面的运行时性能也提升了 30% 以上。除此之外,Astro 不仅支持使用 React 框架,而且支持 Vue、Solid 等在内的各种前端框架,灵活性更高。,其次是最近比较火的新秀框架 Remix,它基于 react-router 管理组件,通过 loader 和 action 的概念尽可能将逻辑代码放到服务端的 bundle,从而减少客户端 JS 的代码体积,同样是崇尚 0 JS 的理念,Remix 却仍然需要全量 hydration,无法完成 partial hydration。此外,Astro 还有两大优势:,React 18 提供了 renderToPipeableStream API,真正实现了 SSR 场景下的 Selection Hydration,主要有如下的几个特点:,
,如果用户在这个过程中点击了 Comment 组件,那么 React 会中断当前对于 SideBar 组件的 hydrate,从而去执行 Comment 组件的 hydrate:,
,那么 Astro 中的 Islands 架构,即 Partial Hydration,和 React 的 Selection Hydration 到底是不是一个东西呢?,答案是否定的。两者存在着非常大的区别:,因此,虽然两者都是在 Hydration 上做文章,但其实是两种完全不同的方案,而且 Partial Hydration 更加通用,限制更少,执行的 JS 更少。,以上就是对 Astro 的介绍和分析,后面有机会给大家剖析一下内部的源码实现。文中如有不妥的地方,欢迎大家评论和指正。最后给大家推荐一些 Astro 的学习资料,方便大家读完文章进一步了解:,[1]Webpack: https://opencollective.com/webpack。,[2]Babel: https://opencollective.com/babel。,[3]Islnads Architecture: https://jasonformat.com/islands-architecture/。
© 版权声明
文章版权归作者所有,未经允许请勿转载。