也算是手搓过博客啦。
经历
最早 WordPress、Typecho 都用过几遍,互联网早期的免费博客大多也蹭了(轻轻怀念博客大巴和不老歌),只不过忍不住想自定义。按理 WP 之类可自定义度不低,但实在太臃肿,还需要服务器,而我又是超爱折腾的白嫖选手……
后来出现了 Github 和静态站点生成器,大喜过望开始 Hexo —— Hexo 到底为什么需要构建这么久啊!反正不想等,遂跑路。
接着发现 Jekyll 和 Github Pages 原生兼容,虽然经常来个快十分钟的更新时间,但是可以直接推送仓库不用本地构建,于是辛辛苦苦学习 Ruby 准备缝缝补补又三年。万万没想到!不知道什么环境更新了,之后各种不兼容,用最新版也不行,修不好,遂放弃。
而且我是每天修改一个错别字选手,东西没写几篇部署倒有几百次感觉怪怪的,.git 目录也会疯狂膨胀,迫切需求一个本地修改云端同步而不需要手工推送的系统,还不能用数据库因为:
- 我的数据都是
markdown文件,导入数据库太折腾了。 - 时不时就想改,修改数据库哪有打开 Obsidian 简单。
- 数据库满足不了我莫名其妙的需求……看当前站点设置就知道了,我把所有内容分为:
这么一看只有两个选项,Server Side Rendering 或者 Single Page Application。一开始觉得 SSR 需要服务器难以白嫖,很是研究了一番 SPA,发现主要问题是很难隐藏后端位置。这时候我的 markdown 文件还存在坚果云,准备使出惯例操作用 Cloudflare Worker 做中转以免暴露真实接口,结果坚果云好像禁了 Cloudflare 的 IP……而且坚果云本来就有用量限制,日常同步无甚问题不过如果要给博客供稿(?),虽然没几个访客 still 不安です。
接着浅尝了 Next,发现这种太现代的东西我不想掌握(……),顺便听了一堆 Vercel 的不靠谱八卦。而且实际效果太卡了!不仅部署后访问卡,调试更是卡得难以忍受,偷窥别人的 Next ISR 站点也卡到不认识卡这个字,不知道怎么优化,可能还是要加钱吧……卡就算了,我的理解是如果卡就不该提供缓存的内容,如果缓存了内容就不该卡,但是它访问也卡,缓存也不刷新,我就不知道该怎么办了
此时转念一想,虽然坚果云不让 Cloudflare 拉文件,但我可以直接把文件丢在 Cloudflare 上啊!R2 还提供 etag 以作版本检查。这会儿还没想到手搓站点,探索了一些可以直接在 Worker 上跑的现成框架,差点写完了 Astro,然后觉得 Astro SSR 实在差点意思,而且大部分时候在手搓,既然如此为什么不彻底一点呢!
思路
记点弯路。
优选
看了很多优选教程但我域名就是在 Cloudflare 买的没法解析到另一个服务,又测了一下大部分地区是绿的遂作罢。
奇怪的是试过另一个免费域名就全红,不知是什么神秘玄学还是 Cloudflare 看后缀下菜碟。
索引
目前的方案是用 Obsidian 的 Templater 插件生成索引文件并同步到 R2,也即是任何地址都需要先拉取索引以确定是否存在对应页面。
比起用软链接一起上传索引,这样做肯定会拖累一点首屏速度,但是一起上传就违背了我不想内容更新后必须推送的初衷。
原理上似乎也可以 bucket.list,但是更慢,还会增加 R2 开销(虽然用不完但我抠门啊),又不方便校验缓存,而且对我来说写 Templater 脚本比较简单,最重要的是拿不到 frontmatter 信息——这就是 R2 作为后端不如 D1 的地方了,但我又不能用 Obsidian 更新 D1。
统计数据
这些倒是存在 D1,一开始傻傻写进页面以为可以靠缓存节省用量,结果发现 1) worker 缓存难以掌控,2) worker 不能调用自己;而且既然访问时会刷新这个数据,缓存就没有意义了,反而多一次开销,直接全部交给前端。
考虑过一并交给 umami 处理,定时拉取当日事件,还在犹豫更新到 D1 还是 KV,KV 理论上更符合场景但不便查询。这样可以省去现在用的前端统计代码,但是得写后端;省一次 worker 开销,但是数据延时很高。说不清哪个方案更小题大做一点……
曾经用的 LeanCloud,不得不说后台体验绝佳但从 worker 走终究慢了一些。
评论这边调研了一下发现现在最先进的似乎是 artalk,然而感觉可以但是没有必要……继续 D1 也能凑合!手搓代码也挺好玩的……顺便搓了个随机头像~
跳转动画
这里又走弯路了,以为必须 pjax 折腾了很久,Firefox 何时才能支持 View Transition!后来发现完全可以用原生跳转实现。
整体开关需要设置在根元素上,这样就不用管 dom 渲染到哪了,另外 dark-mode 需要在 dom 渲染前设置。
pjax 处理滚动位置很麻烦,原生就不用管了,只是需要恢复一下侧栏滚动位置,我是存在 sessionStorage 里的。
页面渲染
刚才说我的数据都是 markdown,之前都是用 marked + highlightjs,后来发现 markdown-it + prismjs 好像更符合我的需求,但是已经给 marked 写了太多 renderer 和 hook,而且 markdown-it 据说更重一些,那就这样吧。
prismjs 居然没有 ESM 支持然后我没研究出来怎么用。22 年官方就说要出 ESM 的 V2,三年又三年……搜到一个社区 ESM 版然而连作者和仓库都找不到。(现在突然想到完全可以前端高亮,不过算了写都写了。)
测试发现 prismjs 比 highlightjs 快一倍,代价可能是语法要手动导入,但我真的喜欢它的高亮效果,义无反顾地换了。
前端样式
在衬线和无衬线之间反复横跳数次最后决定顺从主流,但不得不说移动端还是衬线好看。
CSS relative color 和 light-dark() 支持度实在太低不想写 fallback 不敢用,求你们了快更新浏览器吧。
Firefox 对字体基线的理解就是和 webkit 系差 1px,气死我也!改用 svg 拉倒。
备份推送
本来想改仓库推送,但是官方 action 适配的还是 Wrangler 3.x,我这已经更新换代了,不想自己写了!等更新。