我的 Hexo 博客性能与架构复盘:从“能发布”到“可持续演进”

最近我重新检查了这个博客的源码、主题配置、构建产物和发布流程。它已经能够稳定生成静态页面并发布到 GitHub Pages,但“能访问”和“长期可维护”之间仍然有一段距离。本文记录这次检查的基线、问题优先级,以及后续可以执行的优化路线。
先说明检查边界:下面的数字主要来自本地构建产物和源码扫描,不等同于某个具体设备上的真实网络传输量。真正的优化结果还需要用 Lighthouse、浏览器 Performance 面板和真实用户数据验证。
一、现在的博客是什么架构
当前系统可以拆成三个部分:
- 源码层:Hexo 配置、文章、主题和插件。
- 构建层:Hexo 将源码转换成静态 HTML、CSS、JavaScript 和图片。
- 发布层:生成的
public内容被推送到 Dlog 仓库,再由 GitHub Pages 对外提供访问。
这套方案最大的优点是运行时没有数据库和后端服务,故障面小、成本低、缓存友好。需要继续完善的地方是边界管理:源码仓库、生成仓库、Wiki 和第三方服务之间的关系需要更明确,发布过程也应该只有一个可信入口。
二、构建产物给出的性能基线
| 项目 | 当前观测 | 说明 |
|---|---|---|
| 生成文件 | 约 297 个 | 包含页面、脚本、样式、字体和图片 |
| 生成目录大小 | 约 35.1 MB | 包含约 12.1 MB 的 source map |
| Service Worker 预缓存 | 243 个资源,约 21.6 MB | 首次安装离线缓存的成本偏高 |
| Mermaid | 约 2.57 MB | 当前只有一篇文章实际使用,却被全站加载 |
| 图片 | 167 个 img 标签 | 没有使用原生 loading 属性 |
| 重复资源 | 存在多份相同库文件 | Mermaid、Moment、Waline、APlayer 都出现重复构建产物 |
这些数字说明:页面内容本身不是主要矛盾,资源加载策略才是重点。尤其是全站公共脚本、字体、第三方 CDN 和离线缓存,它们会把一个简单的静态博客变成一组较大的前端运行时。
三、优先级最高的优化项
1. 先处理配置中的安全边界
检查时发现,部分第三方服务配置曾直接出现在版本库配置文件中,包括百度站长推送凭据和评论系统的敏感字段。无论这些字段是否仍然有效,都不应该继续把它们当作普通配置提交。
建议立即轮换已经暴露过的凭据,并改成环境变量或 GitHub Actions Secrets。配置文件只保留服务开关、公开 ID 和非敏感参数。安全问题的优先级高于所有性能优化,因为一个被滥用的 token 会让整个发布链路承担不必要的风险。
2. 统一使用 HTTPS 和正确的站点元数据
当前站点基础配置仍有 HTTP 地址,生成的 canonical、Open Graph 和 sitemap 也会继承这个地址。正式域名应该统一为 https://littledai.cn,并确认 DNS、GitHub Pages 自定义域名和 HTTPS 强制跳转都已生效。
同时应把默认的站点标题、作者、描述和主题链接改成真实信息。它们虽然不直接改变首屏速度,却会影响搜索摘要、社交分享卡片和站点可信度。
3. 不要让 Mermaid 这种大库全站加载
Mermaid 当前约 2.57 MB,而且同一库在生成目录中出现了两份。源码扫描显示,只有 HTML 能力演示文章使用了 Mermaid。更合理的做法是按页面加载:
- 只有检测到 Mermaid 容器的文章才动态导入 Mermaid。
- 或者在 Hexo 构建阶段给使用 Mermaid 的页面加标记,由模板按标记输出脚本。
- 删除主题开发构建和正式构建之间重复的库目录。
这类调整通常比单纯压缩代码更有效,因为它减少的是不需要下载的资源,而不是只减少已经下载资源的几个百分点。
4. 重新设计 Service Worker 的缓存范围
现在的 Service Worker 预缓存了约 21.6 MB、243 个资源,其中包含较大的脚本、字体和页面。这样做离线体验看起来完整,但首次安装成本很高,也容易把旧版本内容长期留在用户设备中。
建议只预缓存离线首页所需的最小应用壳,文章 HTML 和图片采用运行时缓存,第三方资源默认不进入预缓存。还要定义版本更新和旧缓存清理策略。发布脚本在生成后处理 README 的过程中,也要同步考虑 Service Worker 清单,避免清单仍然引用已经删除的 README.html。
四、前端资源还可以怎样减重
图片:把“懒加载”做成浏览器能理解的形式
主题目前主要依赖自定义的 lazyload 属性和 JavaScript 观察器,没有给图片输出原生 loading="lazy" 与 decoding="async"。建议给文章正文图片统一补充:
<img src="image.webp"
alt="有意义的图片说明"
width="1200"
height="800"
loading="lazy"
decoding="async">宽高用于提前保留布局空间,减少 CLS;首屏主视觉则应该使用 loading="eager" 或适当的优先级。对同一张图片提供 WebP 或 AVIF,并用 picture 根据屏幕尺寸选择资源,通常能同时改善 LCP 和流量。
脚本:从“全站大入口”改成按功能加载
主题的主入口会导入懒加载、Mermaid、瀑布流、播放器、本地搜索和页面切换等多个模块。即使最终部分功能没有在当前页面启用,入口本身仍然承担了统一初始化的成本。
可以按照页面功能拆分入口:文章页只加载文章需要的功能,搜索打开时再加载搜索索引,播放器被使用时再加载 APlayer,图表页面再加载 Mermaid。Moment 的完整 locale 包也可以评估是否改用浏览器原生的 Intl.DateTimeFormat,减少一份全语言包。
字体和图标:只发布实际使用的部分
当前产物包含多种字体格式和较大的 Font Awesome 文件。现代浏览器场景下可以优先保留 WOFF2,删除不再需要的 EOT、TTF 等回退格式,并将图标改成按需引入的 SVG。字体文件还应限制字重和字符集,避免为了少量图标传输整套字体。
第三方依赖:性能和可用性要一起评估
首页会请求统计、访问计数、Google 服务、主题 CDN、评论、播放器和多个外部脚本。第三方请求不只影响性能,也会引入 DNS、TLS、跨境网络和服务商故障等变量。
建议按价值排序:不需要的统计和播放器直接关闭;关键脚本尽可能自托管;非关键统计使用 defer 或在页面交互后加载;外部服务增加超时、降级和隐私说明。一个静态博客不应该因为某个计数器不可用而阻塞正文阅读。
五、发布架构应该怎样演进
现在的生成仓库 Dlog 只保存发布后的静态文件,这个方向是可以保留的,但需要明确“源码仓库负责什么、发布仓库负责什么”。建议采用下面的边界:
- 源码仓库:文章、主题、配置、依赖锁文件、部署脚本和架构文档。
- 构建流程:安装锁定版本依赖,执行构建、链接检查、敏感信息检查和可选的 Lighthouse 检查。
- 发布仓库:只接收构建后的静态文件,不手工编辑。
- Wiki:如果它属于博客知识库,应明确是独立站点还是构建输入;不要让它处于“存在但不会随博客发布”的灰色状态。
发布操作应该只有一个入口,例如 npm run deploy。脚本需要在构建失败时立即停止,检查生成目录是否包含首页、CNAME 和 README,最后检查 push 的退出码。这样可以避免“本地看起来成功,但远端其实没有更新”的误判。
六、推荐的实施顺序
- 第一阶段:安全和正确性。轮换敏感凭据,改 HTTPS,修正标题、描述、canonical 和主题链接,确认发布脚本的失败状态可见。
- 第二阶段:立刻减小首屏负担。关闭不使用的全局插件,Mermaid/APlayer/评论/统计按需加载,给图片补充尺寸和原生懒加载。
- 第三阶段:清理构建产物。消除重复库文件,限制字体格式和 Font Awesome 子集,生产发布时不携带 source map。
- 第四阶段:收紧离线缓存。缩小 Service Worker 预缓存范围,增加缓存版本和清理机制,验证新旧版本升级。
- 第五阶段:建立持续验证。每次发布前自动执行构建、链接检查、HTML 关键字段检查,并定期记录移动端 LCP、INP、CLS 和总传输量。
结语
这个博客已经具备静态站点的可靠基础:构建简单、运行成本低、部署目标清晰。下一步不需要大规模重写 Hexo,而是要把资源加载从“主题默认全量启用”调整为“页面按需启用”,把发布从“手工操作”调整为“可重复脚本”,再用真实用户指标验证每次改动。
如果只做三件事,我会选择:先轮换配置中的敏感凭据;再让 Mermaid、播放器和第三方服务按需加载;最后把 Service Worker 预缓存从 21.6 MB 降到一个明确且可解释的范围。这三项分别改善安全性、首屏性能和长期可维护性。
- 标题: 我的 Hexo 博客性能与架构复盘:从“能发布”到“可持续演进”
- 作者: littledai
- 创建于 : 2026-09-10 12:00:00
- 更新于 : 2026-09-10 11:52:45
- 链接: https://littledyc.github.io/2026/09/10/博客性能与架构复盘/
- 版权声明: 本文章采用 CC BY 4.0 进行许可。