从哪说起
老版个人主页(moehome)陪伴了我很久。它本身没什么问题——会动、好看、该有的都有。但时间久了,我意识到一个问题:它只是在构建后安静地躺在那里。打开它,就是纯导航加动态,没有沉淀、没有内容、也没有让人回来的理由。

所以重做之前,我先逼自己回答了一个问题:一个个人主页,在 2026 年,到底该为什么而存在?
这个问题的答案,到项目后期才真正清晰。回头看,这轮重做区别于初代的地方,不是内容、不是技术——是一种思维方式的转变:初代是个人向的实现,满足我自己就行;新版是个人向 + 产品思维,满足我,也考虑使用它的人。配置化、消费层开关、文档、兜底清空——这些都不是“我自己用”需要的东西,是“别人也能用”需要的东西。从个人向到个人向 + 产品思维,是我这次最重要的一次实践。

先想清楚:这个页面放什么内容
这是我的第一个设计决策,也是最重要的一次提问。因为设计这个项目时,我面对一个尴尬:我已经有博客了,它有它明确的定位——长文、深度、沉淀。那这个个人主页放什么?
纯个人的碎碎念文章?我很快否掉了:一个没人看的页面,放再多个人文章也是自我感动,这种内容放在本地笔记里完成就够了,不需要一个网站来承载。
那我积累的摄影作品和回忆呢?它们散落在硬盘里,只有偶尔翻相册时才会被想起。它们需要一个被认真对待的地方——首先是给自己一个重新翻阅的窗口,如果有人恰好看到,那是附加的。于是影集这个板块有了第一个明确的理由。
但只有影集还不够。我需要一个能让人持续回来的东西。这里的“人”不是大众——个人主页的读者,从来都是气味相投的少数。我要的是:对技术、工具、学习这些话题同样好奇的人,路过一次,会想再来。不是自嗨,而是有阅读价值、有信息密度的内容。于是我给了自己一个定位:周刊。它信息密度可以做得非常高,这取决于你怎么定义它——我定义为高信息密度的杂志:技术、工具、学习、阅读四栏目。它不追求日更,但每一期都值得读。
到这一步,这个项目的内容版图才清晰了:
- 动态(Memos)——碎片,日常,让人看到活着的状态。
- 影集——影像与回忆,需要一个更好的窗口,于是有了它。
- 周刊——高信息密度的周期内容,给人回来的理由。
两个内容板块的定位,不是拍脑袋定的,是被问题逼出来的:已经有博客了,还放什么?——答案是,放博客放不下的东西:影像,和高信息密度的周期内容。
所以新版不是推翻重来,是沿着老版的内容结构继续走——但技术栈换了一批(后面专门讲)。我重做的,是底下那套地基——以及想清楚它到底该装什么。
这篇文章不讲配置教程,讲设计决策——为什么这么做,踩了什么坑,以及哪些地方我觉得比老版强。
一、设计语言:从「网站」到「档案卷宗」
老版是我花过心思打磨的版本,有明确的设计理念——零运行时依赖、配置驱动、性能优先,终端风格,还通过 Memos 动态追求「活人感」,留言板做成了终端弹幕交互。我至今喜欢那些想法。但用久了,我发现它更像一张数字名片:聚合社交资产、展示品牌,而内容被放在了博客。重做时的核心问题因此变成:个人主页能不能不只是名片,而是内容本身的发生地?
新版我定了一个隐喻:整个站点是一份档案卷宗。

为什么是档案?我把个人主页理解为“关于这个人的一份档案”——出生年份、编号、登记、索引、附录。这个隐喻一旦立住,所有设计决策都变得有依据:
- 颜色只有 8 个 token,全是纸面质感:底色、纸面、墨色、次要文字、弱化文字、一个强调色、实线、发丝线。
- 板块像档案器件:SPEC 摘要卡、RECORD 登记卡、CATALOG 索引卡、LEDGER 总账、DIRECTORY 号码目录、STAMP 戳记。
- 全站只有一套编号体系:板块是
SEC.NN,页面档案号是NO. MW-2018-NNN,内容条目是MW-ALB-NNN、MW-BLG-NNN。编号不是装饰,是设计语言的一部分。 - 禁止圆角卡片(登记卡打孔和 tag 胶囊是仅有的例外)、禁止阴影、禁止渐变、禁止第二种强调色。这些禁令让视觉高度统一——新页面加入时,“它在档案里是什么”必须先回答。
这个隐喻最大的好处是可维护:以后加任何板块,不用重新设计,只需要回答“它在档案里是什么”。
二、性能:三板斧
个人主页的性能决定的是第一印象。图片是页面最大的体积来源,所以它是优化的主战场——但整站性能是一个体系,图片只是最直观的一环。静态优先的架构、零运行时依赖、构建期 Shiki 高亮、路由预取,共同决定打开速度;其中图片优化做了体系化的三把斧:
- 构建期压缩:所有本地图构建时压缩为 avif(体积约为 webp 的 7 折),开关、格式、质量全部配置化,改一个文件全局生效。
- 按实际渲染尺寸裁剪:列表页的图按容器真实尺寸生成,绝不加载原图。这一项带来的首屏性能提升最直观——快不快,打开就能感觉到。
- 占位 + 懒加载:每张图有一个纯 CSS 的占位层(照片框、便签、文稿的剪影图标),图片走浏览器原生
loading="lazy",加载失败有全局兜底。
一个细节:占位层是纯 CSS mask 实现,零额外请求,颜色走设计 token,明暗主题自动适配。这种“不引库、不增请求”的强迫症贯穿整个项目。
三、SEO:不是玄学,是工程
老版有 SEO 基础,新版把它做到了“体系”级别,因为我的定位是:个人主页应该成为搜索引擎和 AI 最稳定的信息来源。
- 每个页面有完整的 JSON-LD(SiteNavigationElement、Article、ItemList),分页只输出首页的 ItemList。
- 分页页
noindex, follow+ canonical 指回索引首页,避免重复内容。 - sitemap 过滤分页 URL,只保留列表首页。
- 图片按渲染尺寸输出 + 正确格式,兼顾 Core Web Vitals 和图片搜索。
- 站点级 URL 唯一事实源:所有内部链接从配置生成,模板里零 URL 字面量。
其中 llms.txt 是我花心思的一块——给 AI 读的站点说明书:站点是什么、有哪些栏目、站长是谁、联系方式、内容政策、AI 使用说明,全部结构化,构建时动态生成。GEO 实践里我有一条判断:AI 时代,可见性有一半取决于大模型怎么理解你,与其等平台收录,不如主动给机器一个读懂你的入口——何况是做个人品牌呢:当别人问 AI 关于你时,它引用的应该是你的话,而不是别人的转述。llms.txt 就是其中一块明确的数据结构:它是不是最终标准不重要,重要的是「主动让机器理解我」这件事,本身就是我这个定位该做的事。
四、内容:三种节奏,各自独立
定位定了,接下来是实现。三个内容类型对应三种更新频率,各自是独立的体系:
动态(Memos)——碎片,日常。展示带白名单 tag 的公开 memo,只拉 PUBLIC,私密内容永不出现;它有增量刷新(第七节细讲),是唯一能实时更新的板块。
影集——影像,一批一批。content collection + 灯箱,照片级标注(时间、地点、注释),首页有高光定格。
影集在我这里的定位,不是“照片展示”,是一册卷宗——这正好和全站的档案隐喻是同一套语言:专辑就是卷宗里的一册,有封面(专辑卡)、有正文(图文叙事)、有记录(照片级标注)。所以影集详情做文本铺排,不是功能增强,是让隐喻闭环:卷宗里的一册,就该是可翻阅的,而不是摊开在桌上的散页。道理也简单:你也不会买一本毫无文本描述的相册刊物——买它,买的是被讲述的那段旅程,不是印在纸上的照片。

周刊——周期发布。四栏目:技术 / 工具 / 学习 / 阅读。详情页有分级目录轨道、历史期刊索引、上下期导航,阅读版心 680px。
每个板块有独立的开关——关掉任何一个,导航、首页板块、SEC 编号、sitemap 全部自动联动回收,不留死链。配置一个开关,所有关联点跟着走,这是我坚持的「单一事实源」在开关体系上的体现。
五、影集的高光与背景:给页面一点「生气」
影集的定位确定后,我盯着各个核心页面看,陷入白茫茫的思考——结构是完整的,但它好像缺一点「生气」。
思来想去,我想到一个照片标记:highlight。影集里的每张照片可以被打上这个标记,它不是用来排封面的——封面是另一套机制——它是用来「精选」的:被标记的照片,会成为这个页面的灵魂。
具体地,高光照片做了两件事:
- 首页高光定格:精选照片在首页以影像的方式定格展示。
- 背景池联动:被高光标记的照片,会进入背景播放的照片池——整个站点的背景不再是一张静态图,而是一个会呼吸的轮播:默认图与高光影像交替,默认图兼兑底。光是背景就做了两层结构。
这个联动的意义在于:影集不再是一个孤立的内容板块,它的精选照片渗透到全站的气质里。你在浏览任何一个页面,背景可能正在播放你亲手标记的那张照片——这就是「生气」的来源。

而带宽和展示的取舍,我选择交给大家:背景的总开关、高光开关,全部配置化。想省带宽就关掉轮播只留默认图,想有氛围就打开——这背后有一把统一的尺子:凡是依赖使用者环境与带宽的决策——交给他自己;凡是依赖专业判断的体验决策——设计者定死。联动也是自动的:关闭影集时,背景池自动退化为默认图,不留死链。
六、周刊详情页:为了沉静阅读,重构
周刊的详情页是我花了最多心思的一个页面,初版却不是现在这样。
初版是左右布局:左侧历史期刊列表,右侧正文,桌面端吸顶。整套设计做完了,功能齐全——历史导航、上下期切换、所有交互都有。但当我盯着眼前的示例文章时,发现自己一直很难专注地看完。问题不在内容,在侧边——那个历史期刊列表的视觉存在,一直在拉扯我的注意力。
我果断重构了。重构的目标只有一件事:它必须是能让我沉静下来阅读的,不被打断,排版布局不会造成阅读压力。
于是有了现在的样子:
- 正文进入独立的阅读版心(680px),窄到刚好舒适、宽到不像信息流。
- 历史期刊列表从侧边移到了正文之后——需要时自然到达,不需要时绝不出现。
- 右侧只保留一个极轻的目录进度轨道:Scrollspy 跟踪你读到哪,悬停才展开细节,标题只展开当前条目,移动端直接隐藏。
- 评论区和赞助降级为阅读附录(CORR / APPX),在正文结束后才出现。
这个页面的设计哲学很简单:阅读体验优先于信息堆砌。侧边栏功能再有用,如果它干扰阅读,就该被移走或降级。判断标准也很朴素——我自己能不能安静地读完一篇文章。能,才算过关。

沉静阅读这个方向再延伸一步,就是后来的阅读增强:进入周刊详情页(以及影集详情页),背景回归原始态(无默认图、无高光轮播,只剩纸面底色),首次交互后播放一段程序化合成的白噪音——雨声、篝火、夏风树叶,零资源零依赖。这个功能背后有一个设计判断:开关是把决策成本转嫁给用户,所以它只给使用者一个开关加一个选择,至于声音怎么调才好听、背景怎么处理才不打扰——那是设计者该倾泻的事。用户只需要回答“要不要”,不需要回答“怎么要”。
七、动态增量刷新:一个“可选功能”的完整设计
这是新版最“重”的一个功能,也是我思考最多的:动态页能不能不重新构建就更新?
难点在于三件事同时成立:token 不能泄漏给浏览器、增量条目要保持和静态渲染一致的视觉(包括代码高亮)、部署要保持简单。
最终方案是一个“静态优先 + 单端点”的混合架构——Astro 管这叫 Hybrid Rendering(混合渲染:静态默认,单条路由例外地按需渲染):
- 全站仍然是静态产物,只有一个
/api/memos/sync端点是动态的(Node 运行时提供)。 - 构建时把当前展示集合的快照(
{uid: 更新时间})嵌入页面。

- 点击刷新,前端把快照 POST 给端点,服务端拉全量、过滤、diff,返回新增 / 修改 / 删除三组数据。
- 新增插进去、修改原位替换、删除移除——然后整个列表按时间重排。
几个关键决策:
卡片模板只有一个——组件级的单一事实源。 静态渲染和增量渲染共用同一个 Astro 组件 MomentCard,增量端点经官方 Container API 在服务端渲染它,改一处全生效。这个方案是演进而来的:一开始是手写 HTML 字符串生成函数,但字符串化的隐形差异(作用域属性丢失、空白折叠、类名缺失)让我连踩了四个展现层的坑——这正是演进的原因。把模板做成组件后,结构、样式作用域、属性由 Astro 自己处理,整类问题从根上消失。我吃过双份模板的亏,改一处漏一处——所以现在宁可多花重构的功夫,也要把单一事实源做到组件级。
token 只活在服务端。 端点在服务端持有凭据,浏览器永远接触不到。增量条目在服务端用同一套 Markdown + Shiki 管线渲染,代码高亮和静态页完全一致,浏览器不引入第二套渲染库。
删除检测靠快照对比。 Memos 的删除是软删,API 查不到“被删了哪些”。所以用快照对比:上次展示集合 vs 当前展示集合,差出来就是增删改。
这个功能踩了一个很有代表性的 bug:删除一条动态后,列表后位的条目挤进前 30,它相对快照也是“新增”,被无脑插到了顶部——旧条目变成了第一条。修复方式是卡片带创建时间,同步后全列表按时间重排,任何增删改组合都不再错位。
八、抗破坏性变更:接口版本锚点
这是从老版踩坑总结出的纪律。Memos、Artalk 这类外部服务,破坏性变更太频繁了——今天改参数、明天换响应字段,每次都要重新适配。
新版的做法是每个接口在 config 里锚定一个版本号:
// memosConfig.ts
version: '0.30', // 与 Memos 实例版本绑定
// artalkConfig.ts
version: '2.10', // 与 Artalk 实例版本绑定
版本号在 UI 里可见——动态未配置时,占位提示会显示「接口版本要求 MEMOS = 0.30」。升级后端后如果忘了同步,一眼就能看出错配。配套纪律是:适配修复后必须校正版本号,不许遗漏。把“容易忘的事”变成“强制项”。
九、技术栈:收敛,和走向主流
和初代相比,技术选型往两个方向走:收敛,和走向主流。
收敛——确切地说是依赖收敛。这个项目的运行时依赖只有 4 个:Astro、marked、Shiki、hast-util-to-html。零前端框架(React/Vue 一概不引)、零浏览器端运行时库——所有交互(主题切换、懒加载、灯箱、增量刷新)都是原生脚本。技术面越小,升级和维护的成本越低——一个个人站点,不需要养一堆自己都记不住的依赖。
走向主流。Astro 是静态站点的主流框架,Tailwind 是主流样式方案,TypeScript 全量启用,静态优先是主流姿态。选主流不是从众,是为了两件事:一是问题有解——踩坑时文档、社区、搜索引擎都能救你;二是长期可维护——个人主页的定位是「稳定锚点」,一个十年后还能顺利构建的技术栈,才配叫锚点。
这两件事其实是一件事的两面:收敛是控制复杂度,主流是降低风险。前者让这个项目现在好维护,后者让它将来还好维护。
最后
重做个人主页这一年,收获很朴素:想清楚要放什么、把设计做成体系、踩过的坑变成经验。它是按我的方式做的,内容是我的,这一年也是我的。个人主页的答案,大概就是一个朴素的词:我的。
从个人向的实现,到个人向 + 产品思维——这轮重做走完了这一步。我是 MoeWah,AI 时代,想做点自己喜欢的。
如果你也在做个人站点,我的建议只有一条:别急着选框架,先回答“这个页面放什么,给谁看”。内容决定形态,形态决定技术——这是我从这轮重做里学到的最重要的一课。




评论加载中…