时间线还是值得记一下:

  • 2017 年,PHP
  • 2018 年,Jekyll
  • 2019 年,Hexo
  • 2024 年,Astro
  • 2026 年,Self-Built

这件事其实也不是突然发生的。最近几个月,如果你能看到这个博客仓库的提交记录,大概能看出来我一直在删东西:删不必要的样式,删不必要的依赖,删不必要的中间层,上周甚至连 Tailwind 也一起剔掉了(支持裁员 🤡)。

结果删到最后,我发现最大的那层反而还在,就是框架本身。既然都已经做减法做到这里了,那继续在框架上修修补补就没什么意思了,干脆把框架也干掉。

于是我的博客从 Astro 换成了自建引擎,底层是 Bun。

性能

让 Astro 版本和现在这套引擎在同一台机器上跑同样的 build,对比结果:

node_modules -45%
Astro 461 MB
Self-Built 253 MB
构建时间 -87%
Astro 12.1s
Self-Built 1.6s
构建产物 -8%
Astro 1.9 MB
Self-Built 1.7 MB
首页体积 (gzip) -45%
Astro 20.4 KB
Self-Built 11.2 KB
首页体积 (brotli) -46%
Astro 17.9 KB
Self-Built 9.6 KB
首页文件数 -40%
Astro 5
Self-Built 3

Smaller is better.

这些数字说明了一件很直接的事:Astro 在我的博客上做了太多我根本不需要的工作。

package.json 里的依赖条目也少了挺多。dependencies + devDependencies25 个降到 12 个;如果只看运行时 dependencies,则是从 12 个降到 3 个,有两个甚至和前端不相关。

新的引擎其实很简单:markdown-it 负责解析 Markdown,shiki 负责代码高亮,模板函数负责拼页面,Bun.serve() 负责本地开发,build 脚本负责输出静态文件。没有 Vite,没有 Rollup,没有 hydration,也没有额外的内容系统。

还有一个很实际的变化是,build 产物终于变得可预测了。以前首页表面上看也就一个页面,但背后还有 island runtime、renderer chunk、共享 chunk 这些东西,真实体积并不总是直观看得出来。现在这套就直接多了,首页就是明明白白的 HTML、CSS 和 JS 三个文件,没有别的 runtime 藏在后面。

这次顺手还解决了一个 Astro 时代一直很别扭的问题,就是 atom.xml。以前 MDX 正文并不能很自然地直接流进 feed 里,结果 feed 一直是一条额外维护的支线:自定义组件要手工转,HTML 要额外清洗,URL 要额外补。现在,正文本身就是 Markdown,feed 直接吃 Markdown,只有遇到自定义内容块时才退化成 Markdown 友好的版本。页面怎么渲染,feed 怎么降级,都是同一层解释器在决定,而不是正文一套逻辑,RSS 再偷偷长出一套逻辑。

动机

我越来越明显地能感觉到:AI 已经在改变抽象层的成本结构。过去很多框架提供的工程收益,在博客这种低复杂度场景里,开始没有以前那么划算了。

这次重构本身,主要也是 Codex 做完的。它花了大概 3 个小时,把整个站点从头到尾重写了一遍。源码层面的变更大概是新增了 6888 行代码,删除了 6344 行代码。这件事让我重新想了一遍框架的价值。过去这笔交易是成立的:用一点性能,换一套更容易维护的工程结构,模板系统、组件模型、路由约定、内容 schema,这些东西本质上都是为了帮助人更稳定地理解和修改代码。

但 AI coding 打破了这里的平衡。对 Codex 这类 coding agent 来说,一个手写的 HTML 模板函数并不比一个 Astro 组件更难理解。它可以直接顺着 Markdown、模板、样式和脚本一路往下读,再改具体环节。很多原本为了 “降低人类维护成本” 而存在的抽象,在这种场景下没有以前那么必要了。

但是这不等于框架没用了。恰恰相反,有了 AI 之后,我反而觉得框架真正该解决的问题更清楚了:不是继续发明一套更花哨的模板语法,而是把边界、约束、验证、缓存、产物组织这些事情做扎实。语法糖 AI 可以学得很快,但边界不清、产物不可预测、降级全靠补丁,这些才是真问题。复杂应用、多人协作、长生命周期产品,框架依然值钱。

最后

所以这次大概真的不用再换了,系统已经简单到不太值得继续折腾,接下来真正应该花心思的,就是博客内容了。

最后请欣赏这曼妙的 build 输出 ⚡: