上周把个人主页的 Nginx 后端关掉了。整个站点现在是一个 22 KB 的 HTML 文件,gzip 压缩后 6.3 KB,零 JavaScript,服务器只负责一件事:把那个文件吐出来。
这不是为了追求某种极简姿态,而是连续三个晚上被同一类问题打断后做出的决定:那个我几乎不维护的动态页面,正在以一种极其便宜的方式持续消耗我的注意力。
动态页面真正的问题
动态页面不只是「会动」。它有状态,有依赖,有运行时,有一个我必须时不时去看的控制台。一旦装了数据库、缓存、模板引擎、框架,这堆东西就开始以各自的方式衰变:依赖升级、证书过期、日志膨胀、磁盘占满、某个我不知道的 cron 半夜跑起来。
一个普通访客看到的「你的博客打不开」,对应的可能是 7 个不同的故障点。我不想为了一年改两次的页面维护这 7 个故障点。
纯静态能给我什么
纯静态页面没有运行时,所以也就没有「运行时出问题」这回事。它的故障域只剩三个:文件丢了、磁盘满了、Nginx 配错了。这三个我都认得,都修得动。
作者主页不是产品。它是手工艺品。手工艺品用手工工具做最快。
性能上的好处是副产品。一个 6 KB 的 HTML 文件,首屏加载在 100 毫秒以内,移动端几乎瞬开。任何现代框架,哪怕 Astro,最少也要多吐 50 KB 的 JavaScript 才能开始渲染。对一个一年改两次的页面来说,这笔开销不划算。
什么时候应该回到框架
我不会把这套逻辑推到所有站上。框架有它的领地:
- 需要用户登录、个性化内容、动态数据
- 需要服务端渲染来优化 SEO 的大型站点
- 多人协作的后台界面
- 需要频繁更新、几十个页面、内容有交叉引用的复杂站
如果哪天我需要写一个真正的博客,文章多了,搜索和归档开始变得重要,我会用 Astro 或 11ty——它们的产物仍然是静态 HTML,只是写的时候用组件语法。这是「升级路径」,不是「信仰转换」。
关于设计语言
主页的视觉是一点点攒出来的:Fraunces 衬线字体做标题,terracotta 一种强调色,12 列细网格,不对称的左对齐排版。没有渐变,没有阴影,没有圆角,没有 emoji——这些规则不是约束,是省心。
:root {
--bg: #F4F0E8;
--ink: #1B1714;
--accent: #A8451E; /* only one */
}
这套语言的好处是它 几乎不允许我做错事。想加渐变?不允许。想用第二种强调色?不允许。想居中对齐?规则不允许,布局强迫你回到非对称。这就是约束的价值——它把审美决策的成本提前支出了,留给我的是执行。
关于「养一只 agent」
页脚有一行「偶尔养一只 agent」。这不是营销文案。我确实在跑一个常驻的 agent——一个挂在服务器上的对话接口,负责回答问题、写代码、整理笔记。它的状态显示在主页右上的「now」面板里:在线时长、最近一次响应、当前任务。
把 agent 的状态做成页面的一部分,而不是藏在某个子域名背后,是一种姿态上的选择:这个站和那个 agent 是同一个东西的两副面孔,一个是给人看的,一个是给指令看的。
剩下要做的事
- 写一个真正能用的笔记索引页(目前是空链接)
- 把 agent 状态从「mock」换成真实的健康检查接口
- 写一篇关于 Fraunces 这个字体的笔记——它值得单独一篇
主页改完了。今晚可以早睡。