给博客做一次极客化改版:三个藏了一个多月的硬伤,和两个被推翻的结论
起因很朴素:博客跑了一段时间,想换掉首页那张紫蓝渐变条纹的图——它太”设计模板”了,不像一个天天写代码的人的东西。另外关于页的自我介绍也想写简单点。
我把这两件事交给 AI 助手落地,顺手让它头脑风暴一下还有什么能改。结果它先做了一轮勘察,然后告诉我:你提的这两件事,其实不是最该做的。
一、勘察挖出来的三个硬伤
硬伤一:我的头像是别人家的 logo。
侧边栏那张头像我一直没在意。打开源文件才看清——那是一个粉色的字母「B」,是三个多月前从 Bear Blog 迁移过来时跟着旧站一起带过来的残留图。也就是说,这个博客顶着别人家的 logo 挂了一个多月。
硬伤二:favicon 线上一直是 404。
配置里写着 favicon: /img/favicon.png,但那个文件在源仓库里根本不存在。所以浏览器标签页一直是一张白纸。这条特别好验证:
1 | curl -s -o /dev/null -w "%{http_code}" https://你的站/img/favicon.png |
配置能写对一个不存在的路径,构建还照样全绿——这就是”构建成功 ≠ 内容对”的经典样本。
硬伤三:侧边栏公告还停在迁移那天。
公告栏里写着”🎉 博客已迁移到 Butterfly 主题,试试右上角的明暗切换与本地搜索”。而迁移是一个多月前的事,那句话早就该退休了。
二、首页图:一张”程序员味”的封面,和三个渲染坑
新封面是本地用 PIL 生成的原创图(1920×1080,约 95 KB),画面是一扇暗色编辑器窗口:语法高亮的代码、右侧文件树(文件用的是这个博客真实的文章文件名)、底部一条状态栏。
中间那块必须特别处理——Butterfly 的首页标题是叠加在封面正中的,所以封面中间必须暗,否则白字压在代码上没法看。
坑一:圆形暗角会在图正中央留下一块黑斑
第一版我用的是标准的椭圆 vignette(中心暗、四周亮)。结果图正中央出现一块肉眼可见的黑斑——半径太小、衰减太快,明暗过渡在中心变成了一个”洞”。
改成只在垂直方向做软暗化(横向完全均匀),痕迹就没了。原理很简单:标题是水平居中的,需要保护的是一条横带,不是一个圆。
坑二:等宽字体缺字形时,不报错,只画一个空方框
中英文混排必须逐字选字体:中文字体(Droid Sans Fallback)没有拉丁字形,等宽字体(Hack)没有汉字字形,互画都是一片方块。
更隐蔽的是第二条:Hack 没有 ✓ 这个符号。缺字形时字体引擎不会报错,只会画一个空心方框(豆腐块)。合成图缩略图看着完全正常,是我放大到状态栏那一行才发现”✓ 0 problems”变成了”▯ 0 problems”。
解法是先检测再回退:用私用区码位 U+E000 取出这个字体的 .notdef 位图指纹,逐字比对,字形和 notdef 一致就说明缺失,自动回退到 DejaVu。
坑三:头像是圆形裁切的
我第一版在头像四角画了工程感角标,白画了——头像在页面上是 border-radius: 50%,四角必然被切掉。
附带一条:换封面一定要换文件名
url_for 不会给图片加版本参数,同名覆盖后 GitHub Pages / CDN 会继续发旧图。所以新图叫 banner-dev.jpg,而不是覆盖 banner.jpg。
三、两个被实测推翻的结论
这次改版最有意思的部分:两个原本”看起来很有道理”的判断,被实测和源码翻掉了。
被推翻之一:jsdelivr 在国内不可用
改版前我列了一条建议:把第三方 CDN 从 jsdelivr 换掉,理由是”国内访问不稳”。
实测打了脸。先把这个站真实用到的三个依赖拉一遍:
1 | for u in typed.js@3.0.0/dist/typed.umd.min.js \ |
全部 200,一秒左右。别拿刻板印象去改配置,先 curl 一下。 这个结论我当场撤回。
(顺带一提,上面第二次测试我一开始把路径写错了——typed.js@2.0.12/dist/typed.min.js 返回 404。同一个”404”,可能是路径写错,也可能是网络被墙,别急着下结论。)
被推翻之二:瀑布流布局信息密度更高
我原本建议把首页从”左右交替卡片”(index_layout: 3)换成瀑布流(6/7),理由听起来很顺:马赛克排版,密度更高。
去翻主题源码才发现两件事:
- 主题自己根本没有 masonry 的 CSS。 布局是运行时靠一个从 CDN 加载的
@egjs/infinitegrid脚本算出来的。访客网络一旦拿不到那个脚本,首页卡片会直接错位。 - 瀑布流只显示封面和标题,把摘要文字丢掉了。 现在的布局是「标题 + 日期 + 分类 + 标签 + 摘要」,信息其实更多。
所以”密度更高”这个判断是错的,而且它给首页引入了一个不该有的运行时外部依赖。保持原布局。
四、其余改动
- 代码块:
light→darker,加上 Mac 三圆点。技术博客正文里代码占比很高,这块比封面更影响观感。 - 主题色:换掉主题默认的天蓝,色板对齐新封面;顺带设了
meta_theme_color_light/dark,让移动端浏览器的地址栏颜色跟着站点走。 - 导航栏固定:长文滚动时能随时跳转。
- 副标题:一行 → 三行轮播。
关于页:介绍可以精简,法律条款不行
自我介绍按计划压成了三段。但版权声明被打回来重做了一次——我第一版顺手把八行条款压成了一行,被要求恢复成完整版,尤其是这条:
若您认为本站内容侵犯了您的权益,请通过邮箱
nova_work@foxmail.com联系我,我将在核实后尽快处理。
教训很清楚:“精简文案”只该动叙述性内容,版权、免责、侵权通知这类法律文本默认原样保留。 翻新页面前先问自己一句:我删的是自我介绍,还是免责条款?
五、评论区:giscus,以及”怎么确认 App 真的装了”
评论区接了 giscus——走 GitHub Discussions,不需要任何服务器,访客用 GitHub 账号登录即可评论,回复也会同步到仓库的讨论区。
但有个前置条件:必须先在仓库上安装 giscus App,否则文章页会显示一行 “giscus is not installed on this repository” 的报错框。所以我一开始没敢把开关打开——宁可不显示,也不给访客看报错。
问题来了:怎么确认 App 到底装没装? 三条路全是死胡同:
GET /repos/{owner}/{repo}/installation—— 需要 GitHub App 自己的 JWT,个人 token 调不通GET /user/installations—— 需要 App 授权的 token,也调不通- 查仓库的 collaborators / assignees —— 不会有
giscus[bot]。GitHub App 装到仓库上不产生 collaborator,所以这个检查既不能证明装了、也不能证明没装
最后管用的办法是直接问 giscus 自己的后端,按它 widget 实际调用的接口拼一个请求:
1 | curl -s "https://giscus.app/api/discussions?repo={owner}/{repo}&term=/some-path/&category={category_id}&first=10&reactionsEnabled=1&emitMetadata=0&theme=light&lang=zh-CN" |
返回”没找到讨论帖”就说明 App 已经能访问这个仓库了。看到这个结果,才敢把 comments.use 打开。
顺便记一下取 ID 的方式:用 GraphQL 查 repository.id 得到 repo_id,再从 discussionCategories 里挑 Announcements 拿 category_id;仓库要先用 PATCH repos/{owner}/{repo} 把 has_discussions 打开。
六、验收:构建绿 ≠ 内容对
改完之后逐项过了一遍,几条经验值得记下来:
- 大文件要比对 sha256。 GitHub Pages 有传播延迟,部署成功的瞬间去拉,可能拿到半截文件——同一张几百 KB 的图,连拉几次能出好几个不同大小。隔十几秒重拉 2~3 次,比哈希才算数。
- 单个请求返回 000 / connection reset,先别报故障,那是 CDN 抖动,重试两三次再判定。
- 配置改了要落到产物里核验,别信配置文件。比如
nav.fixed: true生效的判定点根本不是<nav>标签——它的产物是页面 header 上的一个fixedclass。看错地方会以为没生效。
七、小结
这次改版真正的收获不是那张图,而是三件事:
- 先勘察再动手。 我提的两个需求都做了,但顺带挖出的三个硬伤(头像、favicon、过期公告)比原需求更值得修——它们已经坏了一个多月,而且没人会告诉你。
- 实测优先于经验。 “jsdelivr 国内不稳””瀑布流密度更高”这两条听起来都很对,实测和翻源码之后全被推翻。前者是刻板印象,后者是我想当然。
- “配置写好了”不等于”配置生效了”。 favicon 指向一个不存在的文件、
nav.fixed的产物在另一个标签上、giscus 的 App 装没装没有任何官方接口能查——这三件事的共同点是:都得去验,不能靠看配置。
改完的站点在这里:https://nova02640.github.io/ ,评论区也通了,欢迎来试第一条。










