大家好,我是何三,独立开发者

6 分半钟→4 分多钟。Cloudflare 的开发者文档网站(8431 个页面),从 Go 编译器时代到 Rust 编译器时代,构建时间直接砍掉 2 分多钟。

这不是什么小打小闹的优化。这是 Astro 7 把整个 .astro 编译器从 Go 重写成了 Rust,顺带连 Markdown 处理管线也换成了 Rust 原生实现(Sätteri),再加上 Vite 8 的 Rolldown 打包器全面替换 esbuild+Rollup——整个构建链条,从编译到打包到渲染,全线 Rust 化。

你要问我什么感受?就俩字:离谱。

性能对比

Go 不香了吗?

这可能是很多人看到这条新闻的第一反应。毕竟 Astro 的编译器用 Go 写得挺好的,2019 年选 Go 做编译器在当时也是合理选择——并发模型成熟、交叉编译方便、生态完善。

但 Rust 这几年在工具链领域杀疯了。

你看 Rolldown(Rust 写的打包器)、Lightning CSS(Rust 写的 CSS 处理器)、oxc(Rust 写的 JS/TS 解析器),还有 SWC、Rome(现 Biome)、Turbopack……基本上你能想到的现代前端工具链,不是已经用 Rust 重写了,就是在重写的路上。

Astro 7 这次玩的更彻底:直接把 Go 编译器整个端掉,换上了基于 oxc 解析 + Lightning CSS 作用域隔离的 Rust 编译器。

说白了,Go 写服务端确实舒服,但 Rust 在"构建一次、到处跑"的工具链场景下,优势太大了——原生二进制、零运行时依赖、WASM 兜底、性能吊打解释型方案。

Astro 团队的原话是:新编译器在 docs.astro.build(约 6313 个页面)上测下来,纯编译环节快了大约 6%。单看这个数字好像不咋地,但注意——.astro 文件的编译从来就不是构建瓶颈。真正的大头是 Markdown 处理和 JS 打包。而这俩,Astro 7 也都 Rust 化了。

整体下来,不同站点的构建提速在 15% 到 61% 之间,那些内容密集型的大站点(文档站、营销站、博客)是最大赢家。

架构对比

再说说那个被干掉的"HTML 自动修正"

这个改动我觉得特别有意思。

老版 Go 编译器有个"贴心"功能:它会在编译时悄悄修正你的 HTML——标签顺序不对?帮你排好。标签没闭合?帮你补上。属性值引号没写全?帮你想办法。

听起来挺好的是吧?

但实际用过的都知道,这玩意儿就是个 Bug 生产机。你本地开发看起来一切正常,部署上线发现某个角落的 DOM 结构跟你写的不一样,查半天发现是编译器"自作主张"帮你修了。体验过的人应该懂我在说什么——那种感觉就像你写代码时,有个看不见的同事在你背后偷偷改你的代码还不告诉你。

Astro 7 的 Rust 编译器完全放弃了这种行为。你的 HTML 什么样,输出就什么样。没闭合就是没闭合,直接报错。这才对嘛——严格模式才是生产力

还有一个细节:JSX 风格的空白处理。以前 <span>Hello</span><span>World</span> 中间会有个空格渲染成 "Hello World",现在没了,变成 "HelloWorld"。要保留空格?得显式写 {' '}。这也是跟 React 对齐的行为。

说实话,刚看到这个改动我是有点慌的——老项目迁移会不会炸?但仔细看了迁移指南,大多数情况下影响不大,因为大部分人写 Astro 组件时并不会依赖那些"偷偷修正"的行为。

Markdown 那部分才是真正的大头

前面说了,.astro 编译只快了 6%,真正的大头在 Markdown。

Astro 7 默认的 Markdown/MDX 处理器换成了 Sätteri(一个 Rust 写的处理器,由 Astro 核心团队成员 Erika 开发)。底层用了 pulldown-cmark 做 CommonMark 解析、oxc 做 MDX 表达式解析。

Sätteri 最狠的是:它把原来需要装一箩筐 remark 插件才能实现的功能,全部内置了

GFM(表格、脚注、删除线、任务列表)——内置,默认开。 智能标点(弯引号、破折号)——内置。 标题 ID、容器指令、数学公式、上下标、Wiki 链接——统统内置。

以前你要写个 Markdown 功能齐全的 Astro 站点,package.json 里得塞一堆 remark-xxx 插件,每个插件遍历一遍 AST 树,几千个页面下来,光插件遍历的时间就够吃个午饭了。

Sätteri 的插件 API 也跟 unified 不一样——插件声明自己关心哪些节点类型,只处理那些节点,不用每次都遍历整棵树。

Cloudflare 那 8431 页的文档站,切到 Sätteri 后直接省了一分多钟。Astro 自己的文档站也从 114 秒降到了 73 秒。

对了,聊到 Rust 和性能——我突然想到另一个用 Rust 重写后起飞的项目:Biome。之前叫 Rome,也是 JS 工具链全面 Rust 化,格式化+Lint 一条龙,速度比 ESLint+Prettier 快几十倍。你要是有兴趣,我回头也可以写一篇。

怎么升级?

升级很简单,一行命令搞定:

npx @astrojs/upgrade

或者手动升级:

npm install astro@latest

新项目直接:

npm create astro@latest

需要注意的兼容性问题: - 如果你依赖了旧编译器"偷偷修正 HTML"的行为,可能需要手动修一下模板 - 如果你用了 remark/rehype 插件,想继续用 unified 管线,可以安装 @astrojs/markdown-remark,Sätteri 不是强制性的 - 如果你用 Sätteri,想启用更多 Markdown 功能,可以这样配:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';

export default defineConfig({
  markdown: {
    processor: satteri({
      features: {
        directive: true,
        math: true,
        headingAttributes: true,
      },
    }),
  },
});

Astro 7 走的"Go→Rust"路线,其实是前端工具链这几年的集体转向。

Rolldown(Vite 8 的一部分)——Rust 写的打包器,比 Rollup 快 10-30 倍,向下兼容 Rollup 插件 API。Astro 7 已经默认集成了。

Lightning CSS——Rust 写的 CSS 处理工具,支持 CSS 模块、前缀自动补全、按需编译,比 PostCSS 快 100 倍以上。

Biome——Rust 写的格式化+Lint 工具,ESLint+Prettier 的替代品。

Turbopack——Rust 写的增量打包器,Next.js 的默认开发打包器。

一个很有意思的趋势:Go 在工具链战场上的地位正在被 Rust 蚕食。不是说 Go 不行了——Go 在云原生、微服务领域依然是王者。但前端工具链这种"单次执行、二进制分发、极致性能"的场景,Rust 确实更有优势。

Astro 7 的 GitHub 地址:https://github.com/withastro/astro

这次 Astro 7 的升级,说白了就一句话:Astro 把"慢"这个问题彻底交给了 Rust 来处理

不是优化代码,不是改进算法,而是直接换语言。这招简单粗暴,但真的好用。

如果你是内容型站点的开发者(文档站、博客、营销页面),尤其是站点规模超过几百页的那种,Astro 7 的升级收益非常明显。如果只是几十页的小站点,提速感知可能不强,但新编译器的严格模式能帮你提前发现一些隐藏的模板 bug,也算值了。

至于那个 Go 编译器——它光荣退役了。工具链领域的 Rust 时代,又进一步。

本文使用 MGO 编辑并发布

关注"何三笔记",回复"mgo" 免费下载使用