avatar
聶.NET
← 返回列表

我把博客从 Vercel 迁到 Cloudflare Pages:仓库变干净了,SEO 变正常了,体验也顺了

最近我给博客做了一次“认真收拾家务”的升级:表面看起来 UI 没变、功能也没少,但内部从部署到生成方式都换了一套更适合内容站的路线。

最直观的变化是:从 Vercel 换到 Cloudflare Pages,然后把以前那种“GitHub 里又放源码又放构建产物”的做法彻底扔掉了——现在 GitHub 只放源代码,构建和发布全交给 Pages 来做。


1)从 Vercel 换到 Cloudflare Pages:不只是换托管

以前用 Vercel,确实方便,也挺快。但越写越觉得:我的博客本质是“静态内容站”,我想要的是:

  • 仓库别越来越臃肿(尤其不想把生成出来的一堆 HTML 也提交进去)
  • 发布流程简单到离谱:写文章 → push → 自动上线
  • 页面是真正的静态页,搜索引擎能直接抓到正文,不要再靠 JS 去渲染内容

所以就干脆把站迁到 Cloudflare Pages,并且顺手把整个构建方式改成更“内容站”的形态。


2)GitHub 只放源码:构建在 Cloudflare Pages 完成

我现在仓库里就留这些东西:

  • posts/:所有文章的 Markdown
  • src/:模板(比如 index.template.html
  • assets/:公共 CSS/JS
  • site.config.json:站点配置
  • build.py / requirements.txt:生成静态页的脚本和依赖

构建产物统一输出到 dist/,并且 不提交

Cloudflare Pages 里就配两行:

  • Build command:python3 build.py
  • Output directory:dist

结果就是:我只要 push,Pages 自动构建+部署,仓库变得非常干净,也不需要再维护“生成文件到底要不要进 git”这种纠结。


3)把 SPA 的“残影”清掉:页面都变成真静态 URL

之前站里还有一些 SPA 风格的东西,比如 /#category/#archive 这种 hash 视图。看起来像页面,实际上对 SEO 很不友好——爬虫不跑 JS 的时候就等于抓了个空壳。

这次我把它们都改成真正的静态页:

  • /category/
  • /archive/
  • /status/
  • /guestbook/

并且保留兼容:老的 hash 链接访问时会自动跳转到对应的新路径,不至于一刀切把旧链接干死。


4)修了个很烦的小毛病:夜间模式切页闪白(1s 那种)

这个问题你如果经常夜间阅读,会非常明显:

开了夜间模式,点进文章/分类/归档时,页面先白一下(像回到白天模式),再变回黑。

根因其实挺朴素:主题是存在 localStorage 里的,但 JS 是页面加载后才读到并应用的,所以第一帧浏览器会先按默认白底渲染。

解决方法也不花哨:把“应用主题”的脚本放到 <head> 的最前面(CSS 之前),并且把主题挂到 html[data-theme] 上,让 CSS 变量一开始就用暗色那套。顺便首帧禁掉 transition,等页面稳定了再恢复。

改完之后,就算手速快狂点,基本也看不到那一下白了。


5)加了 RSS:总觉得博客就该有这东西

我给站点加了 rss.xml,并且让它在构建时自动生成:

  • 新文章上线时 RSS 自动更新
  • <head> 里加了 RSS discovery(阅读器能自动识别)
  • 导航里也留了入口(想订阅的人一眼能找到)

说实话这一步很“复古”,但也很踏实:博客不只是给搜索引擎看的,它也应该能被订阅。


6)文章链接规范化:改成 “日期 + 顺序 ID”,彻底不让 URL 里出现中文

之前文章链接如果用标题当路径,中文、空格、# 这些东西很容易带来编码问题(你会看到各种 %E4%BD%A0... 或者更离谱的转码目录),维护起来也很痛苦。

所以我把文章链接统一成稳定格式:

  • /p/YYYYMMDD-01/
  • /p/YYYYMMDD-02/

好处特别实际:

  • URL 全是 ASCII,复制/分享/兼容性都更好
  • 标题怎么改都不影响链接(链接永久稳定)
  • 搜索引擎收录也更顺(路径规整、不会出现奇怪的编码)
  • 构建输出也更干净(不会生成一堆旧标题路径的兼容目录)

7)构建从 1 分半 → 25 秒:真正慢的是“装 Python”

迁到 Pages 的头几次构建我挺崩溃的:每次都 1 分多。后来翻日志才发现,慢的不是生成页面,而是 Pages 每次都在“安装/编译 Python”。

我最后把会触发版本固定的东西清干净(比如 .python-version / 版本变量之类),让它直接用默认环境,再把 build command 简化成纯 python3 build.py

现在一次更新大概 25 秒左右,终于回到“写完就能发”的节奏。


现在我发文章的流程(终于顺了)

现在写一篇文章几乎就是:

  1. posts/ 写 Markdown(标题/日期/标签/正文)
  2. git push
  3. Cloudflare Pages 自动构建、自动部署
  4. 文章页 + 分类/归档 + sitemap + RSS 同步更新上线

对我来说最舒服的是:我可以把精力重新放回“写内容”,而不是天天跟部署、SEO、路径编码这些细枝末节较劲。