把 Firefly 魔改了五十一版:一份完整的功能清单

7656 字
38 分钟
把 Firefly 魔改了五十一版:一份完整的功能清单
把 Firefly 魔改了五十一版:一份完整的功能清单

这份清单回答一个问题:这个站到底改了哪些东西。

博客是 fork 的 CuteLeaf/Firefly,从 V1.0 到 V1.49 一共 51 版。下面按板块把所有功能列出来,每条附一句它干什么、关键数字是多少。逐条的完整背景、明细和日期都在站内的更新日志页(现在 V1.49、51 个更新日、248 条明细),封面和正文里的截图都是从站上实拍的。

博客日志页:当前版本 V1.49、51 个更新日、248 条详细记录
博客日志页:当前版本 V1.49、51 个更新日、248 条详细记录

首页#

  • 玻璃个人卡片(V1.0)—— 首页壁纸区叠一层毛玻璃卡片:头像、站名、一行快捷导航,下面挂一排彩色标签的社交按钮(GitHub / Email 一键复制 / Bilibili / RSS / 打赏),卡片顶部还有一块胶带装饰。卡片、贴纸、便签依次浮入,从其他页面回到首页时重播。
  • 可拖拽的场景贴纸(V1.0 → V1.18)—— 一开始是 7 张,按住能拖、位置限制在壁纸范围内、刷新复位。后来素材扩到 19 张、桌面固定铺 11 张,排布也从「前后两层错位插空」改成「一排脚踩同一条地面线」——left 不能按等距算,各张基准宽度不同、图片在盒子里居中,按 left 等距排会让视觉中心最多漂 ±11px(1920 宽下)。
  • 贴纸按需加载(V1.10)—— 服务端只输出 data-* 属性、不发图片请求,脚本给抽中的那几张赋 src 才开始下载。手机端只显示 4 张,之前是 12 个请求 / 149 KB,现在就是那 4 张。
  • 第一张动图贴纸(V1.10)—— 「夏娜·甩发」,6 帧、300ms 一轮的动画 webp,从 GIF 转的(帧按并集 bbox 统一裁剪,缩放走预乘 alpha 防止红头发外圈挂黑边)。顺手把体积从 60.2 KB 压到 32.3 KB —— 这张图的 alpha 几乎只有 0/255,有损压缩碰不到它,所以质量可以放心降。
  • 卡片开场自动收起(V1.13)—— 卡片完整停留约 2 秒后整体向右滑出屏幕,露出纯壁纸。收起只做水平位移、不做缩放:手机端贴纸布局读的是卡片 rect 的上下边界,横向挪动不改这两个值,实测收起前后贴纸坐标零漂移,不需要重排。
  • 手动收起与叫回(V1.13)—— 卡片右上角一颗半透明 −,点它立刻收(用减号不用叉,因为这按钮是「先收起来」不是「永久关掉」);收起后右边缘挂出一根竖排小签(默认「关于我」),点它、按回车或空格都能把卡片滑回来,带 aria-expanded。
  • 「隐藏贴纸」开关(V1.13)—— 右下角一颗开关,点一下把首页那排小人收走、再点放回来。收起时从左往右依次淡出、放回时从右往左接上,错开 40ms(可调成 0 = 整排一起动),状态存本地。
  • 贴纸给下滑箭头让路(V1.13)—— 贴纸层 z-index 压在箭头上面,居中那张正好把箭头盖死。没去动箭头层级(那样屏幕中央会多出一颗压在贴纸身上的圆钮),改成让贴纸让路:底部这排从素材里随机抽 10 张、左右各 5 张分列,正中央空出来。
  • 移动端卡片让位(V1.27)—— 屏幕越矮卡片和箭头离得越近,而卡片下方那排社交标签是刻意垂到面板外的吊牌,先被糊住的就是箭头。脚本按实测算出「卡片视觉底边 + 12px 净空」到箭头之间差多高,把差值写进 CSS 变量抬升卡片;屏够高(390×800 及以上)算出来是 0,等于一点都不动。
  • 首页动态滚动条(V1.23)—— 横幅下方一条横向滚动的条子:左边「动态」胶囊、中间滚最近 12 条站长动态、右边「更多」,悬停暂停,点某条跳到对应那条。它当 #main-grid 的 grid item 横跨左右侧栏,这样点下滑箭头滚到它时不会被甩出视口,塞进文章列又会太窄。DOM 默认 display:none、数据在页面渲染完之后才异步拉,拉不到整条不显示;实测掐断接口后 FCP 仍是 1112ms、CLS 为 0。
  • 关闭水波纹动效(V1.4)—— 桌面端与移动端的水波纹动画都关了,少一块持续占用主线程的 canvas 绘制。

新增页面#

  • 朋友圈 /moments/(V1.1)—— 把所有启用友链的最新文章聚成一条时间线,按时间倒序、支持分页。构建期抓各站 RSS/Atom,友链配置里没填 rss 的会去探常见路径和首页的 <link rel="alternate">;抓取结果写成本地快照兜底,单站失败不阻断构建。页面里另有一张「随机文章」卡片,每 5 秒换一篇,本站标蓝徽章、推荐友链标金徽章。快照刷新走 GitHub Actions 定时任务,每周六 06<00> 跑一次并自动提交。
  • 朋友圈的来源配比(V1.6)—— 原本整体按发布时间倒序,结果被聚合站霸榜。改成按「本站 30% / Blog 40% / 博客社区 30%」交错:每一步挑「当前实际落后目标比例最多」的那一组取下一篇,组内仍是新的在前。每个友链的取文上限也从 6 篇提到 12 篇 —— 本站只有一个源,上限 6 篇时最多只能贡献 6 篇,而 40 篇里要占 3 成就得 12 篇,怎么配都凑不出来。已知副作用:几个月没更新的友链会掉出 40 篇名额。
  • 站点统计看板 /analytics/(V1.12)—— 七个模块:四色总览卡、访问脉冲(7 / 30 / 90 天切换 + 手动刷新 + 数字滚动)、推送节奏热力图(按 GitHub 提交时间,带贪吃蛇动画)、访客活跃时间、设备与浏览器环形图、地域分布(中国地图 + 流量来源占比)、Waline 评论统计。数据走 Umami 公开分享接口、浏览器直连,取数要同时带 x-umami-share-token 和 x-umami-share-context 两个头,少一个就 401。
  • 看板改成本站配色(V1.14)—— 整页主色从写死的 #2d7cff 换成 var(--primary),kicker、小标题、折线图、时间范围切换一次性全部跟随。推送数从 1695 修正到 252(仓库是 fork,git log 不加 --author 会把上游 CuteLeaf/Firefly 的历史全算进来);推送热力图改用 GitHub 原版绿(这块本来就在模仿贡献图,跟主题色反而怪),「访客活跃时间」那块仍跟主题色;两个状态角标从右上角挪进标题块 —— 那两处 header 都是 space-between,右侧恰好都是角色插画,角标一直被顶上去压住它们。
  • 番组计划 /bangumi/(V1.16 / V1.17)—— 最早开的是 /bilibili/(构建期拉追番追剧清单,221 条、均分 8.7),后来关掉换成番组计划:浏览器实时拉 api.bgm.tv 的收藏,动画 308 部、看过 277 部。改成访客侧拉取是刻意的 —— 构建期不请求任何外部接口,收藏更新也不用重新部署,代价是首屏靠 JS 渲染。封面图床有防盗链,得把 *.bgm.tv 加进 noReferrerDomains,不加会整页裂图。
  • Steam 游戏库 /steam/(V1.25)—— 拥有游戏数、总时长、近两周时长、等级徽章,以及按时长排序的全部游戏列表。两条取数路径自动切换:有 STEAM_API_KEY 走 Web API 拿完整列表,没有就退回 steamcommunity 公开 XML 的精简模式(只有常玩几款,快照打 partial 标记、页面上给提示)。封面图按 apps/<appid>/header.jpg 直接拼,省掉「先拉商店详情拿 hash」这一步。
  • 留言板群聊风格(V1.22)—— 把 Waline 默认评论框换成聊天窗口:气泡列表、公告栏、成员列表、表情包、图片上传、回复 / 编辑 / 删除、30 秒自动同步。后端一个字节没动,还是原来那个 Waline,但这一页的评论前端从完整客户端(100.9 KB gzip,走第三方 CDN)换成自写组件(23.4 KB brotli,同域托管),净减约 82 KB;50 KB 的组件样式也从全站 main.css 挪进这一页,只有 /guestbook/ 加载。137 个新文案走自建语言表,没动 src/i18n/。
  • 留言板的一串修复(V1.22 / V1.26 / V1.30)—— 旧评论框和 Waline 后台发的回复显示不出引用块(解析回退到原生 pid / reply_user 字段,判据用 typeof pid === 'number',因为一级评论的 pid 是 null 而不是缺失);移动端公告栏被左上「留言板」、右上「成员」两个悬浮按钮压住(给会话区垫出 3.25rem 让开浮层式头部);桌面端面板顶边正好贴着首屏壁纸下沿、太挤(往下压 2rem,只改 margin-top 不动高度)。公告弹窗还加了「不再显示」,写进 localStorage 之后该访客不再自动弹。

留言板:群聊风格的聊天窗口,右侧是成员列表
留言板:群聊风格的聊天窗口,右侧是成员列表

  • 博客日志页 /blog-changelog/ —— 就是这份清单的来源:每条改动记一行版本号、一句话摘要、背景说明和明细。V1.32 给它瘦过一次身:「背景」段落收进折叠区,默认只留版本徽章和标题,顺手把最长的两条描述从 1835 字压到 246 字。
  • 站长动态 RSS /dynamic/rss.xml(V1.24)—— 动态页有了自己的订阅源,和页面同一份数据(当前 12 条),每条跳回 /dynamic/ 对应锚点。动态页头部「N 动态」旁边注入了一个 RSS 按钮(小屏只留图标),head 里同步埋了 rel="alternate"。
  • 书签导航悬停预览(V1.31)—— /booknav/ 的卡片悬停展开该站首页截图:卡片从 flex 改成 grid,封面独占一整行、高度 0 → 7rem 展开,图片首屏不加载,真悬停 / 聚焦过才请求。截图是离线跑脚本批量截的,带拦截校验 —— 渲染后 HTML 的前 4000 字符命中 Cloudflare 403 / 验证页特征就丢弃,再用 sharp 算通道标准差、纯色空白页也丢弃,否则悬停展开会是一张白图。

友链#

  • 卡片悬停展开首页截图(V1.20)—— 鼠标停在友链卡片上,顶部展开一张对方首页的截图(高 7rem,截页面上半部分而不是居中裁剪,更像「首页」)。12 张 webp 总共 190 KB 左右,全部离线截好存在站内,首屏一张都不加载,脚本本体也只在 /friends/ 才按需拉。
  • 自助申请(V1.21)—— 友链页第 2 步多了个「进入申请表」按钮,点进去是 GitHub Issue 表单。提交后机器人自己去访问对方站点,校验三项:主站可达、友链页可达且与主站同域、页面里确实挂了本站链接 —— 全过才写入配置并上线,没过就在 Issue 里回复具体原因。写入只往数组头部插一条,已有条目的字段和注释一个字节不动,并按域名去重;校验脚本零第三方依赖(只用 Node 内置 fetch),不需要装 Chromium,单次运行约 20 秒。
  • 社区单独分区(V1.33)—— 把「博客社区」那批(友链社区、博客聚合站)从主网格里挪到下方独立一栏,不再和个人博客混在一起。分区配置就是脚本顶部一个数组(标签、标题、说明),顺序即页面顺序,没归入任何分区的卡片进「其他」兜底;主题原有的标签筛选与搜索照常跨区块生效。
  • 头像防盗链(V1.1)—— 友链页与朋友圈的头像统一加 referrerpolicy="no-referrer",解决 BlogsClub 头像 404;它那张头像另外改成本地托管,不再依赖对方站点资源。

全站视觉与交互#

  • 卡片深色描边(V1.29)—— 参考站的卡片有一圈很明显的黑描边,扒下来发现主题自带 enable-card-border 开关、本站早就开着,只是边框色用了 --line-divider(亮色下是 8% 的黑,淡到看不出轮廓)。换成纯黑、宽度 2px,样式走页脚注入。难点全在补清单:文章卡片、侧栏组件、分页按钮先统一,自建页再逐个补(留言板主面板与两个弹窗、Steam 四类卡片、朋友圈的三种变体、书签导航、友链卡片、Bilibili 卡片、更新日志页);顺便发现有几类卡片 border 只写了宽度和颜色、没写 border-style,那样是画不出来的。暗色下自动切纯白。代价是悬停时边框不再变主题色,反馈改由位移和阴影承担。
  • 页脚两行数字(V1.11)—— 第一行是建站运行时间(天 / 小时 / 分 / 秒,秒数逐秒跳,切到后台标签页直接停掉定时器、切回来立刻重算);第二行是今日访客、今日访问、本站访客、本站访问四个指标,数字从 0 滚到目标值。令牌缓存 24 小时、今日数据 60 秒、全站数据 5 分钟,请求挂在 window.load 之后的 requestIdleCallback 上,不进首屏关键路径;取数失败时整行保持隐藏,既不显示 0 也不显示「加载中」。
  • 全站「最近评论」(V1.37)—— 全站右栏「最新动态」下方挂一个最近评论(移动端在底部组件栏):直连 Waline 公开接口拉最新 8 条,每条含头像、昵称、相对时间、「评论于 /路径」。接口没给头像时用昵称首字 + 哈希色相的文字头像垫底,图片加载失败自动露出文字;结果在本地缓存 2 分钟。
  • 最近评论收窄到首页(V1.38)—— 全站显示改成只在博客首页(含分页)显示,文章页不再出现、也不占布局。
  • 开往入口(V1.36)—— 申请加入开往(Travellings)之后,顶栏加了一个外链入口,页脚徽标放在萌 ICP 备案号下方(黑白两版都自托管、跟着明暗模式切,不依赖对方站点可用性,也不因图床抽风而空白),移动端抽屉里也有。
  • 顶栏挤压的老毛病(V1.36)—— 顶栏在 1024–1599px 会把标签压成竖排。根因是「1280px 起导航图标出现、同一档搜索框展宽」,两头一挤就溢出;现在这个区间隐藏导航项图标(下拉面板里的条目图标保留)并把项目内边距从 16px 收到 8px。
  • 开往补回图标(V1.39)—— 加的是 material-symbols:train-rounded(列车正面,呼应页脚徽标里的车头造型)。上一版「省空间所以只留文字」的理由在这档宽度已经过期:紧凑模式的选择器会命中所有下拉容器的直接子项,开往同样被隐藏,实测余量仍是 1024px +40px、1280px +194px,一字没变 —— 图标只影响 ≥1600px,那里余量本来就够。
  • 「关于」菜单补自建服务(V1.40)—— 音乐播放器是自建服务,书签导航里有、顶栏右上角也有个图标按钮,但从「关于」这一排站内服务入口反而点不进去。补上外链项,位置跟书签导航里那条对齐;顺手把「本站评论系统」这个名字砍成「本站评论」。
  • 评论回复折叠(V1.42)—— 每条评论下的回复默认展示 2 条,多出来的先收着,还有剩就给个「展开更多(还剩 M 条)」、每次再放 5 条;全部摊开后变「收起回复」,点一下回到 2 条。回复本来不超过 2 条的评论完全不碰,连按钮都不插。折叠只认 .wl-quote 的直接子节点 —— Waline 点「回复」时插进来的编辑框不是这个类,不会被误伤;观察器挂在 body 而不是 #waline,因为后者会随无刷新切页被整个替换掉。
  • 回复带上引用(V1.43 / V1.44)—— Waline 的二级回复原本只有一行「@昵称:」,回的是他那句话里的哪一句全靠猜。其实 Waline 在 DOM 里留了线索:回复正文第一行 wl-reply-to 里那个 a 标签的 href 就是被回复评论的 objectId,而每条评论节点的 id 正好也是它 —— 顺着锚点把目标找回来,摘成引用块插在下面;点它会滚到原评论并闪一下,目标正被折叠收着时先自动展开到那一条。V1.44 又瘦了一次身:原生那行「@昵称:」不再显示(引用块里已经写明回的是谁),引用块去掉底色只留左边一根主题色竖线、前面补一枚 ↩ 符号,浅底色挪到回复正文上。
  • 页脚去掉开往徽标(V1.45)—— 顶栏那个入口已经在,页脚这枚就成了重复,撤掉,顺带删了自托管的两张黑白图。
  • 动态页评论跟上全站(V1.46)—— 动态页每条动态的评论跑在同源 iframe 里,而那个页面走的是不带页脚的布局,拿不到全站注入的样式与脚本,于是成了唯一一套「不折叠、无引用」的评论区。现在由父页面把样式和两条脚本代投进 iframe:样式按 id 从页脚 clone 过来(单一来源,改一处两边一起变),脚本直接复用现成的。回复折叠与回复引用在动态里照常生效。
  • 动态页照着朋友圈重做(V1.48)—— 参照一个同主题的站把动态页整套换了样子。动手前先扒了两边的 DOM,发现上游动态卡片的元素本来就齐(头像、作者、时间、地点、置顶徽章、图片网格、评论按钮一个不缺),差的只是样式 —— 所以没新开页面,纯样式覆盖加一点脚本注入就够,主题源文件零改动。卡片加了左侧主题色竖条、头像改成 40px 圆并描一圈主题色、昵称走主题色、图片网格换成固定 100px 方块(单图仍保留完整显示不裁剪);封面区是上游压根没有的东西(封面大图、浮出的头像、昵称签名、写说说按钮、置顶条),外壳写在页脚、由一个脚本搬进正文,封面图从壁纸池里随机挑、每次进页面换一张;页面头部那层卡片壳连同大图标一起拆掉,内容收上去当封面卡片的下半截;评论区加了三件事 —— 按钮标评论数、只自动展开真有评论的条目、把 Waline 那个大编辑器压成一行(点进去自动还原)。
  • 俺妹指针主题(V1.47)—— 全站鼠标指针换成《俺妹》:亮色用高坂桐乃、深色用五更琉璃(黑猫),各 28 枚,共 112 个文件约 700 KB。切图时踩到一个反转:这批图标是「深色描边 + 白色填充」,人物衣服和箭头内部都是纯白、跟页面背景同色,按处理贴纸那套「全局去白底」会把图形掏成空壳 —— 改用孔洞填充,被描边围住的白色算图形内部,只把连到裁切框边缘的那片白做成透明。CSS 那边把「用哪张图 + 热点坐标」全塞进自定义属性(:root 放桐乃、html.dark 放黑猫),28 条规则只写一遍、切主题只换变量;每条三档声明覆盖高分屏,代码块则保留系统原生 I 型光标。
  • 右栏天气预报(V1.49)—— 参考站右栏挂着一张天气卡,从标题竖条到大号温度、两列指标(风力、能见度、体感温度、湿度、气压、空气质量、云量、紫外线、降水量、降水概率、日出日落)、污染物浓度和「收起」按钮整套复刻。数据走 uapis.cn 的免费接口,一次请求返回全部字段、中文描述现成、浏览器直连不用 key;最舒服的是不传参数时按请求方 IP 定位 —— 每个访客看到的是自己所在地的天气,想固定成常驻地就填 FIXED_CITY。全站显示,桌面挂右栏 top 容器末尾、小于 768px 换挂到移动端底部组件栏,跨断点自动搬运;默认展开,点一下压到 9.5rem 只露地点与温度,状态记在会话存储里。接口有配额(1500 credits / 31 天),所以本地缓存给到 30 分钟。两个坑:参考站那套图标是 Astro 构建期按需渲染的 symbol、动态插入的节点取不到,最后把 34 枚图标的 path 内联进脚本;指标网格的 auto-fit 在 280px 右栏算下来只排得出一列,把卡片顶到 925px,改成固定两列后落到 613px。

性能#

  • CDN 分层缓存(V1.2)—— HTML 加 s-maxage=86400 边缘缓存(浏览器端保持 max-age=0,发新文章立即可见);/_astro/ 哈希资源缓存一年并标 immutable,重新部署自动换哈希无需手动刷新;/assets/、/pagefind/、/pio/ 缓存 30 天;/api/ 边缘缓存 1 小时、浏览器不缓存。另加一个部署后自动从 sitemap 提取全站 URL 预热边缘缓存的工作流。
  • 壁纸瘦身(V1.3)—— 桌面 4 张 + 移动 3 张全部转 WebP q90:14.3 MB → 1.0 MB,首屏图片加载量减 93%。配套写了个一键压缩脚本,支持强制重跑,以后换壁纸跑一遍就行。同期给 HTML 缓存加了 stale-while-revalidate=604800:CDN 缓存过期后先给访客旧页面秒开,后台同时拉新页面更新缓存。
  • 首屏提速(V1.4)—— 贴纸图压到实际显示尺寸(源图 360×480,被 CSS 的 max-height: 104px 夹到约 78×104),8 张从 331 KB 降到 127 KB;修掉「装饰层入场动画要等 9 张图全部加载完才开始」的阻塞(改成只等卡片自身的图,兜底超时从 1400ms 收到 400ms);favicon 从 88 KB 换成 8.9 KB —— 原来那个 .ico 其实是一张 221×183 的 PNG 改名的,重新生成了真多尺寸 ICO。首屏合计少传 283 KB。
  • 预取刹车(V1.45)—— 把 Lighthouse 抓的逐帧截图导出来一张张看才发现,首屏最大的那笔流量根本不是图片:Swup 视口预取会让链接只要露出 20% 面积并停留 500ms 就被提前下载,而首页第一屏正好有 7 个链接满足条件(卡片导航 5 个 + RSS / 打赏),一次抓回 483 KB 的页面 HTML,占移动端总流量的 34%。关掉之后首屏少发起 14 个请求。
  • 标题不再姗姗来迟(V1.5)—— 之前一直以为拖慢首屏的是壁纸或毛玻璃卡片,读了 trace 才确认最大元素是卡片里那行标题文字:它借用了通用内容关键帧、起点是全透明,而浏览器不把全透明的元素算作「已经画出来」,最大元素的计时就被硬生生推迟;更绕的是这个 0.36 秒的起点还得先等卡片里的小图加载完。换成专属关键帧(起点 opacity: 1,只保留 12px 的位移)后延迟从 0.36 秒砍到 0.08 秒,入场逻辑也拆成两段 —— 文字动画不再等图片。
  • 壁纸请求为什么晚(V1.45)—— 那张 89 KB 的壁纸请求直到 638ms 才发出:它藏在 <template> 标签里,浏览器解析 HTML 时根本看不到它,必须等内联脚本把它克隆进 DOM 才开始下载。
  • 别让小图抢带宽(V1.45)—— 侧栏头像改成懒加载并去掉 fetchpriority=high:一个小头像被标成高优先级,而真正的首屏标题和壁纸反而只有默认优先级。同时给 /images/ 和 /favicon/ 补上 30 天缓存头,这两类之前落在默认规则上、响应头是 max-age=0, must-revalidate,等于每次访问都要重新校验一遍。
  • 站内搜索提速(V1.41)—— 搜索一直有种说不清的「慢」:敲完字要等好几秒。两件事叠在一起。一是资源链太深 —— pagefind.js、worker、wasm、索引分片严格串行依赖,而它只在用户碰到搜索框时才开始加载,几跳的等待全落在输入之后;二是取数请求数和结果条数同阶,主题对全部结果逐个调 data(),而每个 data() 就是一次 fragment 请求,搜个常见词命中 45 条就是 45 个请求。现在新增一个预热脚本:首屏空闲或鼠标碰到搜索框时就把 worker 起来、wasm 编译好、索引读进内存;再用一层 Proxy 只让前 6 条真拉正文(面板本来就只显示 5 条),实测 45 → 6,结果数组长度不变所以「查看更多 N 条」的计数仍然准确。顺带补上「回车 = 进第一条结果」(isComposing 为真时放行,不干扰中文输入法)。移动网络与省流模式下跳过预热,不抢带宽。

素材与相册#

  • 贴纸素材的抠底与压缩(V1.9 / V1.18)—— 白底原图用「亮度 + 低饱和度谓词 + 四角洪水填充」抠底:靠连通性保住角色内部的白衬衫,同时吃掉落地灰影。画笔感强、浅色部件直接贴背景的那 6 张,本地抠图会咬掉剑刃和衣领,改用云端前景提取后再本地收边;云端抠图会把日期和画师签名当成前景留下,用「只保留面积 ≥ 最大连通域 5% 的块」一次清掉。
  • 相册「首页贴纸原图」(V1.8)—— 12 张全分辨率原稿:9 张 1440~2048px 的原始 PNG,加上 3 张只有 192px 版本的早期素材(那就是现存最清晰的形态)。相册索引自动收录,封面手动指定为桐乃那张欢呼。
  • 相册「夏娜表情」(V1.10)—— 9 张表情画稿:发怒、叹气、大哭、慌乱、懵圈、挥手、星星眼、脸红、蜜瓜包,原图不压缩存档。
  • 相册「统计页插画」(V1.15)—— 把 /analytics/ 页面里的 7 张插画归档成新相册:页首横幅、两张角色立绘(保留透明通道)、四张概览卡片插画。三张 PNG 转 webp(质量 90、不放大、保留透明通道),四张本来就是 webp 的原样字节拷贝,避免二次有损压缩。
  • 壁纸池扩充(V1.7 / V1.18)—— 桌面池加了夏娜横版(1920×1005)、黑猫夏装横图(1920×1080),移动池加了夏娜竖版(1080×1920)和一张抠掉品红底、保留透明通道的黑猫(1080 宽,背后露的是页面底色,浅色 / 深色模式各自适应)。V1.4 起开启多张壁纸自动轮播,每 5 秒切一张。
  • 相册清理(V1.19)—— 「移动壁纸」相册删掉品红底的那张原图,「贴纸」相册删掉与单张高清版重复的九宫格源。
  • 相册「俺妹指针主题」(V1.47)—— 两张指针主题总览图(桐乃 / 黑猫各 28 枚)原图字节一致、零压缩归档,站点实际加载的是据此切出的 public/images/cursors/。这类原样直出的相册不另建 gallery-originals/ 副本 —— 那个目录只给压过 webp 的相册用。

工程与基础设施#

  • 内容与主题分离(V1.28)—— 文章搬进独立的私有仓库,主仓库 src/site-content/ 进 .gitignore,从此合并上游不用再为文章目录解冲突。构建前脚本从 CONTENT_REPO_URL 浅克隆内容(--depth=1),本地已有内容时自动跳过;本地开发走 CONTENT_DIR 加增量同步脚本,dev.sh / dev.bat 一键完成「同步 → 后台」。
  • 内容推送自动部署(V1.28)—— 内容仓库加了一个 workflow:push 之后调用 Vercel Deploy Hook 和 Cloudflare 部署挂链,文章推上去就自动重新构建上线。平台只监听主仓库,内容仓库推它感知不到,这一步是必需的。
  • Tailwind 扫不到内容目录(V1.34)—— 友链页的申请模板本该一条字段一行,实际挤成一整段。查下来不是 CSS 写错:内容目录在 .gitignore 里,而 Tailwind v4 的自动内容探测会跳过被 git 忽略的路径 —— 于是「只出现在内容文件、主题源码从没用过」的工具类永远不会生成,类名照旧挂在 HTML 上、规则却不存在。解法是加一个登记表:同步脚本顺带扫内容里出现的 class 名、写进一个没被忽略的文件,内容仓那边一个字都没改。
  • 构建不再被接口拖垮(V1.35)—— 有一轮推了改动、等了十几分钟线上还是旧页面,翻日志才发现部署根本没成功:站长动态的 RSS 在构建期拉 Memos,实例解析到国内 IP、构建机在海外,直连必然超时;落到回退分支后又踩了个 bug —— processor.render() 是异步的、返回 { code, metadata },之前把 Promise 当 HTML 字符串往下传,走到剥标签那步就抛 html.replace is not a function。更麻烦的是上游适配器里那句 promise.finally() 派生出的 promise 没人接管,fetch 一失败就是未处理的 Promise 拒绝,在 Node 24 下直接把构建进程带走,调用方的 try/catch 拦不住。现在构建期先做一次带 4 秒超时的可达性探测,连不上就完全不调接口;另外对 Memos 请求失败产生的未处理拒绝加了窄范围兜底,只忽略超时、连接重置这类网络错误并打印告警,其它拒绝照旧抛出。
  • 给悬停封面做体检(V1.31)—— 书签导航的悬停封面走「构建期生成一份静态 JSON」,清单里没有对应条目时前端是 if (coverUrl) 直接跳过,静默不展开、零报错。所以把体检塞进那个静态 JSON 路由:比对配置与清单,缺了就 console.warn 列出来并附补图命令,零联网、零耗时。

写在最后#

这五十一版几乎全部落在 src/config/**、public/** 素材和新增的独立文件上 —— 跟上游的实际差异是 522 个新增文件加 66 个改动,而真正落进组件和页面目录的只有 5 个(CoverImage / WallpaperSection / Profile / friends.astro 加了 1 行 / guestbook.astro),剩下的全是数据文件(github-card-data.json / lqips.json)。原因很实际:上游更新勤,改动挂在外面才好合并,出问题也能整段摘掉。

这套「挂外面」的做法最近又救了一次场:动态页那条链路要补的是全站评论增强,而动态的评论跑在 iframe 里、那个页面没有页脚 —— 换作直接改页面或组件,就得跟上游的 comments.astro、DynamicInlineComments.astro、dynamic-inline-comments.ts 三个文件纠缠;挂在页脚注入上,只多了一个新脚本就解决了。

逐条的完整明细还是看更新日志页。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
把 Firefly 魔改了五十一版:一份完整的功能清单
https://www.9ll.uk/posts/blog/modssummary/
作者
HY
发布于
2026-10-14
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
给书签导航加悬停预览:复刻友链流程,多踩三个坑
博客书签导航那 64 个书签也加上了悬停预览:鼠标放上去展开一张该站点的首页截图。做法是把友链页那套原样搬过来,但书签和友链不是一个东西,中途多踩了三个坑——同域名多条会互相覆盖、Cloudflare 的 403 页截出来是张「看着正常」的白底黑字图、headless 的默认 UA 直接被拒。最后 56 条拿到了能看的封面。
2
给友链页加了悬停预览:12 张截图离线截好,主题文件一行没动
博客在 blog.amamo.top 的友链页看到鼠标悬停弹首页截图的效果。我这边的约束是不能动主题源文件,所以换了个做法:截图用本机浏览器离线截、转 webp 存进仓库,卡片用一段独立脚本在浏览器里现场拼。12 张封面一共 190 KB,悬停之前一张都不加载。
3
给博客加了张更新日志页
博客羡慕 rainzt.cn 的博客日志页,把它的页面结构扒下来,用 Firefly 自己的组件体系重做了一遍。全程只新增三个文件,不碰主题源码,以后合并上游更新不受影响。顺便把折叠动画从 max-height 换成了 grid-template-rows。
4
给博客装了个朋友圈:把友链的更新聚成一条时间线
博客羡慕 rainzt.cn 的朋友圈,把它搬进自己的 Firefly:构建时抓取所有友链的 RSS 合流成时间线,快照兜底,GitHub Actions 每天自动刷新。纯静态,不用服务器,只新增文件不碰主题源码。后来又给时间线加了层来源配额,不让聚合站霸榜。
5
给博客首页加了张可拖拽贴纸卡片:一次合并友好的魔改
博客看到 rainzt.cn 的首页毛玻璃卡片和能拖动的贴纸羡慕了,扒下来装到自己的 Firefly 上。全程只新增文件不动主题源码,以后还能正常合并上游更新,顺便踩了一堆 CSS 的坑。后来又按性能数据把入场动画拆成两段、关掉了 Swup 视口预取;最后一轮重做了贴纸排布,桌面并成一排、手机收成一行,还加了张动图,并把贴纸改成延迟加载——手机端从 149 KB 降到 47 KB。最近又给卡片加了「开场两秒后自动收起」、右下角的贴纸开关,并让底部那排改成随机抽 10 张、左右各 5 张分列,把正中央让给下滑箭头。
随机文章随机推荐

评论区

Profile Image of the Author
HY
Hello, I'm HY.
公告
迷茫.... 为了访问速度,本站将会在11月上旬至中旬迁移到0dm.cn并完成备案
分类
标签
最新动态
站点统计
文章
74
分类
8
标签
192
总字数
161,979
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录