博客重构
创建于 Feb.25 2024

不觉博客已然存活了近十个年头,具体可以移步页脚的 Copyright 提示窗查看天数,距上次调整博客样式也已有四年,这次趁着空闲简单实现了新样式,介绍一些关于这个版本的设计想法,当然目前版本还只实现了一些基本功能,很多模块会在后续逐步补齐,关于博客的其他历史可以移步 About Site 页面(尚未整理完)

内容分类

在规划里本次改版的博客文字内容分类如下

  • 博文(Posts):正常的博客长文,内容较为详实
  • 随笔(Essays):短篇文章,可以是思考、开箱这样的内容
  • 动态(Activities):可以是博主的阅读、游戏、观影等动态,也可以是个人维基条目更新或社交媒体发言,还能点击进入详情页查看个人评分和短评等(还未完全实现)
  • 呓言(Memos):一些不吐不快的个人言论或是灵感
  • 书摘(Excerpts):类似 Kindle 的阅读标注(还未实现)
  • 片段(Snippets):代码片段和配置文件等

目前阶段实现了博文、随笔、动态、呓言和片段部分,随笔部分还在纠结如何设计才适配短篇文本的阅读体验,随笔参考 Shiro 默认展示最新的文章,可以通过左侧边栏切换阅读,也可以通过左侧边栏底部链接前往随笔列表。书摘的规划是一整个页面,包含摘抄内容、笔记、位置、时间几个字段,可以通过筛选查看某本书或某段日期的书摘内容。把长短篇拆分的灵感源于 捕蛇者说 电报群里某群友推崇的独立博客设计,琢磨了一番感觉确实有道理。

本次改版内容分类最大的变动应该是增加了名为“信息流”的独立页面,这个页面会按照时间顺序混合排列展示上面的那些分类内容,不过为了观感仅有博文和随笔会全部出现,其他类型会选择性展示。在上个版本的博客中有个 History 页面算是最早对这个想法的尝试,那个页面主要是把阅读、观影、游戏等动态相关内容用时间线组件串联作为独立页面,经过实践发现仅放动态的话页面的信息密度太低了不适合当做独立的一级页面。后面逐渐改进成现在的样式,可以在一个页面里简略展示博主一个时间段内博客里发布的各种类型内容,不过,在下拉菜单里还是会保留单独的内容类型页面。

技术栈

后端

上个版本前后端的所有交互都是基于 GraphQL,所以本次改版最初的规划是使用 Hasura 替代原有服务作为 GraphQL 后端提供绝大部分的 CRUD 功能,最后迫于当前版本前端的 GraphQL 调用对于 SSR 的相性太差,会有各种不明原因水合报错,因而只选择了在后台的 SPA 部分使用 GraphQL 操作,这样也没有必要使用 Hasura 了。

后端服务则继续选用熟悉的 FastAPI + Strawberry + PostgreSQL 来快速实现,包管理则从 poetry 切换到了 PDM,使用 PDM 也有一段时间了,也曾在前司的产品里推动切换过,各方面都很顺手。

前端

前端是读者最能直观感受到博客改版的窗口,也是我所不擅长的方面。最初考虑过 Svelte,但是发现生态问题导致使用成本略高,出于对开发时间的考量还是选用了较为熟悉的 Quasar,毕竟上个版本就是 Quasar + Apollo 实现的。构建工具方面恰逢 Quasar 的 dev 分支刚刚支持 Vite 5.0 而选用,对比之前的 Webpack 体验真是上了一个台阶。模板引擎继续选用 Pug,写起 Vue 来感觉非常舒服直观。

最早使用 Quasar 的原因是它是个 Material Design 样式的框架,本次 CSS 样式则是在 Quasar 原有的样式上加上了 Tailwind CSS,早就闻其大名却没有使用的场景,这次正好体验下,博客域名里带 wind 用个 tailwind 似乎也没啥问题,不过因为是配合框架使用的,很多组件会渲染很多无法直接使用类名的标签,还是有一定的样式代码量。

然后是代码高亮部分,之前一直使用的是 highlight.js,这次切换成了 shiki,直接将样式硬编码成 Inline Style,还提供各种高亮、聚焦等效果语法糖,轻便的同时功能更为强大。

网络

之前博客是部署在 Vultr 的东京机房,因为开通较早所以网络相当不错,各地直连基本全在 100ms 以内,我在家访问基本稳定在 80ms,而这次改版博客新申请了大阪机房的机器,回程线路绕道北美甚是折磨直接到了 280ms 的延迟,不过下载带宽比东京机房的机器大了一倍以上,咬咬牙忍了。

设计风格

这次博客的风格设计参考了很多独立博客,我的收藏夹里专门有个分类叫“UI参考”,专门用于保存令人眼前一亮的博客设计,四年来存了有约 200 个站点,不过很可惜里面很多站点现在已经无法访问了。这版的风格主要参考了 「静かな森」和「Reorx’s Forge」。

背景

博客背景有多个变化阶段,第一阶段是全屏图片背景加上半透明卡片组件,第二阶段是仅在题图使用图片背景,题图上有着标题和文章的元数据,其下方的正文部分则是纯色的,排除背景图花里胡哨的干扰。这次改版经过考量完全移除了图片背景,整个博客使用纯色系背景,保持阅读的专注。目前只开放了深色模式,浅色模式放在后面迭代。

这次还给博客的背景图上尝试加了层 SVG Filter,给页面营造了噪点效果,显示效果虽然比引用噪点图片差了一点,后面考虑再微调下看看能否有更好的观感。

然后为了避免纯色背景单调的感觉,还加上了低对比度的 Canvas 动画,在保留动感的同时避免对阅读产生过多干扰。文章发布时的动画只有一种,来自 Codepen 的 气泡纸屑,后面会考虑每次访问使用随机动画,以及在特定季节优先有对应的效果。

主题色

前端的主题还是取为 Natsukaze,灵感来自很喜欢的一张专辑——狐の工作室的 夏風NatsukazeOto,在我的想象里,夏日的风就应该是既热烈又轻柔的绿,因此博客的历史主题色一直是 #6AB344,这次的主题色主要出现在后台面板里,前台用的相对较少,更多使用的是由绿向黄的渐变色。

排版

文章正文作为最主要的部分,其文字排版部分还是会很大程度影响博客的观感。很早就关注了 字谈字畅(TypeChat)与不少网页排版相关的站点,学到了很多相关知识,由于时间关系本次的文字排版主要参考了 VitePress 的主题,其余像中英文混合排版、段落排版等问题会在后续调到满意后更新。

组件相关

图片

曾经博客的图床使用的是七牛,域名是 cdn.kuon.me,由于备案被吊销后无法通过域名访问资源,且七牛改版后不提供直链访问桶里文件,因此将图床切换成了 Bitiful,允许直链存储桶的同时支持媒体查询。在之前实现过根据浏览器的兼容性来依次按需加载 avifwebp 格式的文件,avif 格式在有损压缩下的文件大小及性能表现远超 webp,通过 CanIUse 查得 avif 的支持率已有89%了,因此本次改版所有图片均使用 avif 格式加载。

关于图片的展示方式,目前仅有平铺,后续会加上走马灯形式。另外图片使用 medium-zoom 库实现图片点击缩放,。目前放大后还是经过压缩的图,还在考虑如何实现来平衡原图与展示图的大小

评论

在很长的时间里(2016.02.22~2024.03.02)博客一直使用的是 Disqus 评论,早期的 Disqus 使用体验还挺不错,实现起来非常简单而且外观也不算差,只是后来发现每次请求都会引用一堆文件和跟踪请求,还会在 Dev Tools 的 Console 里报一堆错,实在感觉可靠不了一点。考虑到保留历史评论的原因所以一直没下定心更换,这次比较了几个评论系统后更换成了自建的 Artalk,把数据掌握在自己手里,也把历史评论迁移了过来,唯一的遗憾大概是没法迁移历史评论的头像,Artalk 基于 Gravatar 的头像甚至带来了种回到最开始使用 Wordpress 的恍惚感。

鉴权

博客的鉴权方案为了尝鲜试过很多种方案,从最早的 OTP 到 SSL 双向认证再到 16 年后一直使用的 Hawk + U2F 双因素认证,当时使用 U2F 主要是为了给 Yubikey 清灰,加上只需要轻触一下即可登录博客的手感很爽。这次改为了 JWT + WebAuthn,大体上没有什么变化,只因注意到 U2F 升级为 FIDO2 了,便想尝试一下所谓的无密码认证,具体的开发流程和 U2F 倒是大差不差,区别就在于浏览器端的支持变好了。上线后在生产环境可以直接凭借 Bitwarden Chrome Extension 直接生成与使用 Passkey,确实有点意思,当然也踩了坑,这个插件在测试环境整了个好活,最后开了隐身模式来避免它的干扰。

尾声

想到哪写到哪,后续有改动的话会同步修改本文。