优化日志2.0
关于优化2.0
写在前面
我也没想到,这篇优化日志居然写到了2.0。与其说是日志,不如说是一堆小修小补的折腾记录——把遇到问题过程中的优化思路和踩过的坑整理归档,方便日后回查总结,也希望能给同样航向的船长一点参考。
本文档仅记录近期自己对网站的美化与优化,也可能是看似无意义的小踩坑。
近期收录的都是我问题的踩坑以及我的解决思路,你可以在本文 get:
- Service Worker 404 报错修复
- Live2D 看板娘懒加载与首屏提速
- Google Fonts 本地化与子集化
- 第三方资源本地化
- 自定义 CSS 瘦身
- COS 图片压缩与 PicGo 图床配置
- 反向推理与应急回退指南
阅读提示:本文档仅为个人的踩坑记录。深知自己代码功底尚浅,文中难免存在逻辑漏洞或不够优雅的写法。如果您发现任何错误,或有更好的优化方案,恳请各位大佬不吝赐教,感激不尽!
目录索引
- Service Worker 404 报错修复
- Live2D 看板娘首屏阻塞排查与延迟加载实践
- Google Fonts 本地化与子集化
- 第三方资源本地化
- 自定义 CSS 瘦身
- COS 图片压缩与 PicGo 图床配置
- 反向推理与应急回退指南
1. Service Worker 404 报错修复
1.1 问题记录
现象: 生成本地预览时在 Network 面板中,/sw.js 请求返回 404 Not Found。
控制台报错:
Uncaught (in promise) Error: A bad HTTP response code (404) was received when fetching the script. |
问题分析:
- 排查出即使不需要 PWA 功能,这段代码也会每次都执行,白白发一次请求。
- 在开发模式下(勾选了 Update on reload),
controllerchange事件触发后会导致页面陷入无限刷新的死循环。 - 直接访问
GLOBAL_CONFIG可能导致未定义报错。
1.2 排查记录
通过排查 _config.butterfly.yml 的 inject.bottom 配置,发现手动注入了一段 Service Worker 的注册代码。该代码在每次页面加载时都会强制请求 /sw.js,可我在博客根目录实际并未部署该文件,导致 404。
排查过程中发现以下三个坑:
- 坑1:缺少容错处理 — 原代码没有
.catch(),找不到文件时浏览器直接抛出红色的Uncaught (in promise)错误。 - 坑2:缺少防无限刷新机制 — 在开发模式下(勾选了 Update on reload),
controllerchange事件触发后会导致页面陷入无限刷新的死循环。 - 坑3:全局变量直接访问 — 直接访问
GLOBAL_CONFIG可能导致未定义报错。
1.3 解决思路
为 navigator.serviceWorker.register() 方法增加 .catch() 容错处理,当文件不存在时,静默处理错误,不再向控制台抛出红色异常。同时引入 refreshing 标志位拦截重复的 controllerchange 事件,防止无限刷新。使用 IIFE(立即执行函数)包裹代码,避免污染全局命名空间。
1.4 优化后代码
<script> |
1.5 踩坑总结
| 踩坑点 | 原因 | 解决方案 |
|---|---|---|
| 控制台报红 404 | 没有 .catch() 捕获错误 | 添加 .catch() 静默处理 |
| 开发模式无限刷新 | controllerchange 事件重复触发 | 引入 refreshing 标志位 |
GLOBAL_CONFIG 未定义 | 直接访问全局变量 | 使用 window.GLOBAL_CONFIG 安全访问 |
2. Live2D 看板娘首屏阻塞排查与延迟加载实践
2.1 问题记录
2.1.1 现象描述
在对博客进行本地化部署预览后,通过浏览器开发者工具(F12 → Network 面板)进行性能分析时,发现页面首屏渲染存在明显的”一卡一卡”现象。
2.1.2 Network 面板异常
在 Network 面板的瀑布流(Waterfall)中,观察到以下异常:
- 核心模型文件
hijiki.model.json的加载状态长时间处于(pending) - 该文件未能及时下载完成,导致浏览器的渲染线程被阻塞,后续的图片、字体等关键资源排队等待,引发视觉上的卡顿
2.1.3 存在问题
首屏加载卡顿直接导致:
- 加载异常:打开页面后,文字和图片加载缓慢,视觉体验不流畅
- Lighthouse 评分低:首屏渲染指标(FCP、LCP)不达标,影响 SEO 排名
- 资源竞争:Live2D 模型文件与首屏核心资源(HTML、CSS、关键图片)争夺有限的网络并发连接数
2.2 排查记录
2.2.1 排查思路
针对 (pending) 状态,我排查方向主要集中在以下两方面:
| 排查方向 | 怀疑原因 | 验证方式 |
|---|---|---|
| 网络层 | 模型文件体积过大,或服务器(腾讯云 COS)响应过慢,导致下载超时 | 检查 COS 控制台响应时间、文件大小 |
| 执行层 | Live2D 的初始化脚本在页面加载时同步执行,抢占了浏览器的网络并发连接数和主线程资源 | 审查 Network 瀑布流、检查脚本加载方式 |
2.2.2 排查过程
第一步:审查 Network 瀑布流
- 发现
hijiki.model.json长时间处于(pending)状态 - 该文件的依赖资源(
.png贴图、.moc动作文件)也同步发起请求
- 发现
第二步:排查服务器响应
- 登录腾讯云 COS 控制台,检查对应存储桶的响应时间
- 确认服务器响应正常,排除网络层问题
第三步:深入分析脚本加载方式
- 审查
_config.butterfly.yml的inject配置 - 发现 Live2D 的初始化脚本
L2Dwidget.min.js通过<script>标签同步加载,没有defer或async属性
- 审查
第四步:确认根因
- 同步加载的脚本会阻塞 DOM 解析,浏览器被迫分配资源去下载和解析看板娘模型
- 在 HTTP/1.1 协议下,浏览器的并发连接数受限(通常每个域名最多 6 个),大体积模型文件迅速占满带宽
2.2.3 原因分析
经过排查,确认卡顿的根本原因是 Live2D 插件的同步加载机制与首屏渲染产生了资源竞争,具体问题是两个方面:
模型文件体积庞大:Live2D 看板娘不仅需要加载
.model.json配置文件,还会触发大量贴图(.png)和动作文件(.moc)的并发请求。在 HTTP/1.1 协议下,浏览器的并发连接数受限,这些大体积文件会迅速占满带宽。渲染阻塞:Live2D 的初始化脚本(如
L2Dwidget.min.js)通常在 DOM 解析时同步执行。在页面主内容(HTML、CSS、核心图片)尚未渲染完成时,浏览器被迫分配资源去下载和解析看板娘模型,直接导致了首屏加载的阻塞。
2.3 踩坑记录
坑1:初期误判为网络层问题
排查初期,我首先怀疑是腾讯云 COS 服务器响应过慢或模型文件体积过大导致的下载超时。在 COS 控制台逐一检查了响应时间和文件大小,结果服务器响应正常,排除了网络层问题。这一轮排查浪费了不少时间,说明遇到 (pending) 状态时,不能只盯着网络层看,执行层的同步加载同样会导致资源长时间 pending。
坑2:同步加载的隐蔽性
Live2D 的初始化脚本通过 <script> 标签同步加载,没有 defer 或 async 属性。这种同步加载方式会阻塞 DOM 解析,但浏览器不会报任何错误或警告,我的控制台干干净净,只有通过 Network 面板的瀑布流才能发现模型文件长时间 pending 的异常。如果只看控制台日志,很容易忽略这个问题。
坑3:延迟时机的选择
在实现延迟加载时,最初尝试使用 DOMContentLoaded 事件监听来触发看板娘的显示。但 DOMContentLoaded 事件在 DOM 解析完成后即触发,此时部分外部资源(如图片、CSS)可能尚未加载完毕,导致看板娘提前显示时页面尚未完全渲染,视觉上仍然不够流畅。最终改用 window.load 事件,确保所有资源(包括图片、样式表等)全部加载完成后再延迟显示看板娘,体验明显好转。
2.4 操作方法
2.4.1 核心策略
采用 “默认隐藏 + 页面加载完成后延迟显示” 的异步加载策略:
- CSS 隐藏:在页面初始渲染时将 Live2D 容器强制隐藏(
display: none),避免占用首屏渲染空间 - JS 延迟:监听
window.onload事件,确保页面所有核心资源加载完毕后,再通过定时器延迟初始化并显示看板娘
2.4.2 步骤一:编写 CSS 隐藏样式
在 Hexo 根目录的 source/css/ 下新建或修改 custom.css,添加以下样式:
/* 默认隐藏 Live2D 看板娘,避免阻塞首屏渲染 */ |
说明:使用
!important确保覆盖主题默认样式,防止其他 CSS 规则将此元素设为display: block。
2.4.3 步骤二:编写 JS 延迟加载逻辑
在博客根目录的 source/js/ 下新建 delay-live2d.js,编写以下脚本:
window.addEventListener('load', function() { |
说明:
- 使用
window.addEventListener('load', ...)而非DOMContentLoaded,确保所有资源(图片、CSS)加载完成后再执行setTimeout延迟 2000ms(2秒),给浏览器足够的时间完成首屏渲染- 通过
document.getElementById('live2d-widget')获取容器元素,仅修改display属性,不重新创建 DOM
2.4.4 步骤三:通过配置注入
在根目录的配置文件 _config.butterfly.yml 中,利用 inject 字段将上述文件注入到页面中:
inject: |
说明:
- CSS 放在
inject.head中,确保在页面渲染初期就生效,看板娘容器从一开始就是隐藏的- JS 放在
inject.bottom中,确保 DOM 解析完成后再执行,避免阻塞页面渲染
2.4.5 步骤四:验证效果
hexo三连:
hexo clean && hexo g && hexo s |
通过调整 Live2D 的加载时机,成功将非首屏关键资源从核心渲染路径中剥离。具体手段包括:
- CSS 隐藏:通过
display: none在初始渲染阶段隐藏看板娘容器 - JS 延迟加载:通过
window.load+setTimeout实现 2 秒延迟显示 - 主题注入配置:通过 Butterfly 的
inject机制将 CSS 和 JS 分别注入到<head>和页面底部
这次恰巧印证了我的一个前端性能优化原则:对于不影响首屏内容的第三方组件,应尽量采用延迟加载(Lazy Load)或异步执行(Async/Defer)策略。
2.5 踩坑总结
| 踩坑点 | 原因 | 解决方案 |
|---|---|---|
| 初期误判网络层 | 只检查 COS 响应时间和文件大小 | 同时排查执行层的同步加载 |
| 同步加载隐蔽性强 | 浏览器不报任何错误 | 通过 Network 瀑布流发现 pending |
| DOMContentLoaded 时机过早 | 外部资源尚未加载完毕 | 改用 window.load 事件 |
3. Google Fonts 本地化与子集化
3.1 问题记录
现象: F12检查发现 Network 面板显示 css?family=Titillium+Web&display=swap 请求耗时高达 700ms+。
页面表现: 因跨洋网络延迟或 DNS 解析问题,导致页面文字长时间不可见(FOIT,Font Visible Instantly Timeout),严重阻塞渲染。
3.2 排查记录
- 检查
hexo-google-fonts插件配置,确认插件已安装但远程请求未切断。 - 查阅主题文档,发现主题本身也自带了 Google Fonts 的加载开关。
- 确认需要同时关闭插件和主题的远程字体加载,才能彻底切断跨洋请求。
3.3 解决思路
- 彻底切断对 Google 远程服务器的请求,改用本地部署字体文件。
- 安装
hexo-google-fonts插件,在根目录_config.yml中配置所需字重和子集化(仅加载拉丁字符,极大减小体积)。 - 在主题配置中关闭默认的远程加载开关(
Google_fonts: false)。
3.4 核心配置
# 博客根目录 _config.yml |
3.5 踩坑总结
| 踩坑点 | 原因 | 解决方案 |
|---|---|---|
| 字体加载慢 | 请求跨洋 Google 服务器 | 本地化部署字体文件 |
| 双重加载 | 插件和主题同时加载远程字体 | 同时关闭两者的远程开关 |
| 字体体积大 | 下载了完整字符集 | 开启 subset: true 仅下载拉丁字符 |
4. 第三方资源本地化
4.1 问题记录
现象: inject 配置中引用了 font-awesome-animation.min.css 的外部 CDN 链接。
页面表现: 国内加载不稳定,可能拖慢页面初始化速度。
4.2 排查记录
- 审查
inject.head配置,发现引用了 jsDelivr CDN 的远程链接。 - 确认该 CDN 在国内部分地区访问缓慢或不稳定。
- 决定将资源下载到本地,替换远程引用路径。
4.3 解决思路
使用 npm 下载该库到本地 source/css/ 目录,并修改引用路径为本地路径。这样无论外部 CDN 是否可用,页面都能正常加载动画效果。
4.4 操作命令与配置
终端执行:
npm install font-awesome-animation --save |
修改前:
# _config.butterfly.yml |
修改后:
# _config.butterfly.yml |
4.5 踩坑总结
| 踩坑点 | 原因 | 解决方案 |
|---|---|---|
| CDN 国内不稳定 | 服务器在海外 | 资源本地化 |
| 删除远程链接后 404 | 本地文件未复制 | 先复制文件再改路径 |
media="defer" onload | 需确保本地文件路径正确 | 用绝对路径 /css/xxx |
5. 自定义 CSS 瘦身
5.1 问题记录
现象: 自定义 CSS 代码(yao.css)中包含已删除的时钟卡片样式(无效代码),且滚动条样式缺乏 Firefox 兼容性。
具体问题:
.card-clock相关样式指向已删除的 DOM 元素。#footer-wrap a和.footer_custom_text颜色值重复,可合并。- 滚动条仅使用了
-webkit-scrollbar伪元素,Firefox 用户看不到自定义滚动条。
5.2 排查记录
- 审查
yao.css文件,逐条检查样式选择器对应的 DOM 元素是否还存在。 - 发现
.card-clock的 HTML 元素已在之前的优化中被删除,但 CSS 样式未同步清理。 - 检查滚动条样式,发现只写了 WebKit 内核的伪元素,缺少标准 CSS 属性。
5.3 解决思路
- 删除无效的
.card-clock样式,减少无意义的文件体积。 - 合并相同颜色的选择器(
#footer-wrap a和.footer_custom_text),精简代码。 - 补充标准的
scrollbar-width和scrollbar-color属性以兼容 Firefox。
5.4 优化后 CSS
/* 作者名颜色 */ |
5.5 踩坑总结
| 踩坑点 | 原因 | 解决方案 |
|---|---|---|
| 无效 CSS 堆积 | 删除 HTML 后忘记清理 CSS | 定期审查 unused CSS |
| Firefox 滚动条不显示 | 只写了 WebKit 伪元素 | 补充标准 scrollbar-width 属性 |
| 选择器重复 | 不同选择器设了相同颜色 | 用逗号合并选择器 |
6. COS 图片压缩与 PicGo 图床配置
6.1 问题记录
现象: Network 面板显示首屏存在一张 6.5MB 的 JPG 图片,这是目前拖慢网站速度的最大元凶。
隐患: 作为网站图床,图片被其他网站盗链会导致流量费爆炸。
6.2 排查记录
- 检查腾讯云 COS 控制台,确认存储桶的访问权限、数据处理规则及防盗链配置。
- 检查 PicGo 插件配置,确认上传路径与自定义域名是否匹配。
6.3 踩坑记录
- 坑1:缓存未刷新 — 修改防盗链或压缩规则后,CDN 节点上可能还缓存着旧的大图,导致优化不生效。
- 坑2:压缩过度 — WebP 质量设太低,手机端图片模糊。
6.4 解决思路
- 无感压缩:开启腾讯云数据万象的”极智压缩”自动处理,URL 保持不变。
- 安全防线:PicGo 存储桶设置为”公有读私有写”,绑定自定义域名并开启 CDN 强制 HTTPS,配置 Referer 白名单防盗链。
6.5 操作归档
COS 极智压缩验证
# 访问图片时,检查响应头 |
PicGo 图床配置速查
| 设置项 | 推荐值 | 原因 |
|---|---|---|
| 访问权限 | 公有读私有写 | 网站访客必须能看图,只有你能传图 |
| 域名 | 自定义域名 + CDN | 默认域名太慢且丑,CDN 加速全国访问 |
| 协议 | 强制 HTTPS | 适配现代浏览器安全策略 |
| 图片处理 | 开启极智压缩 | 实现”原链接访问,后台自动瘦身” |
| 安全防护 | 开启防盗链 | 防止别人偷用你的图,导致你破产 |
7. 反向推理与应急回退指南
当服务器崩了或优化过度时,请按此逻辑路径自救
关于自救,这是我多年排查经验的方法
7.1 六步排查法
- 看日志:
hexo s --debug查看具体报错行号。 - 查变更:回顾最近一次
git log或文件修改时间。 - 停插件:注释掉
_config.yml中所有新加插件,恢复默认。 - 清缓存:
hexo clean && rm -rf node_modules && npm install。 - 验环境:
node -vpnpm -v确认版本未自动升级。 - 读文档:回到本文档对应章节,确认是否遗漏配置项。
7.2 回退命令速查
# 紧急停止服务 |
7.3 优化操作清单回顾表
| 优化项 | 风险等级 | 预期收益 | 回退方案 |
|---|---|---|---|
| SW 容错处理 | 低 | 消除控制台报错 | 删除 .catch() 逻辑 |
| Live2D 延迟加载 | 低 | LCP 提升 1s+ | 移除 setTimeout 脚本 |
| 字体本地化 | 中 | 消除 FOIT,首屏提速 | 开启 font-display:swap |
| 第三方资源本地化 | 低 | 消除 CDN 不稳定因素 | 还原远程 CDN 链接 |
| CSS 瘦身 | 低 | 减少文件体积 | 还原旧版 yao.css |
| COS 极智压缩 | 低 | 流量费减半 | 关闭数据处理 |
结语
折腾的意义不在于完美,而在于掌控。每一次报错都是系统在与你对齐认知。愿这份日志成为你数字花园里的”路标”,无论走多远,都能循迹而归。



.jpg)



