
问题是怎么发现的? #
今天下午 3 点,我打开刚部署好的博客:
https://ai.mylog.vip页面加载出来了,但感觉有点慢。
打开 Chrome DevTools 的 Network 面板,一看:
Finish: 3.2s
DOMContentLoaded: 2.8s
Load: 3.2s3.2 秒。 对于一个静态博客来说,这个时间太长了。
作为对比,我打开 yu-wenhao.com(参考网站):
Finish: 0.8s
DOMContentLoaded: 0.6s0.8 秒。 差了 4 倍。
问题出在哪?
第一步:找到瓶颈 #
打开 Lighthouse,跑一次性能测试:
Performance: 68/100
First Contentful Paint: 2.1s
Speed Index: 3.2s
Largest Contentful Paint: 2.8s
Total Blocking Time: 450ms主要问题:
- ⚠️ 字体加载慢(Google Fonts 阻塞渲染)
- ⚠️ CSS 文件太大(未压缩)
- ⚠️ 图片未优化(WebP 格式)
- ⚠️ 没有 CDN 加速
优化方案 #
1. 字体加载优化(最关键的瓶颈) #
问题 #
原来的配置:
<link href="https://fonts.googleapis.com/css2?family=..." rel="stylesheet">这会阻塞渲染,直到字体下载完成。
解决方案 #
预连接 + 异步加载:
<!-- 预连接,提前建立 DNS 和 TLS 连接 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- 字体加载 -->
<link
href="https://fonts.googleapis.com/css2?family=Satoshi&family=Newsreader&display=swap"
rel="stylesheet"
media="print"
onload="this.media='all'"
>
<!-- 降级处理(如果 JS 禁用) -->
<noscript>
<link href="https://fonts.googleapis.com/css2?family=..." rel="stylesheet">
</noscript>原理:
preconnect:提前建立连接,省掉 DNS 解析和 TLS 握手时间(约 200-300ms)media="print" onload="this.media='all'":异步加载字体,不阻塞渲染
效果:
字体加载时间:800ms → 200ms
FCP 改善:2.1s → 1.2s2. CSS/JS 压缩和合并 #
问题 #
Hugo 默认会生成未压缩的 CSS/JS 文件。
# 检查文件大小
ls -lh public/css/
main.css 245K # 太大了!
custom.css 12K解决方案 #
Hugo 内置了资源压缩功能,配置 hugo.toml:
[build]
[build.buildStats]
enable = true
disableIDs = true
[[build.cachebusters]]
source = "assets/watching/hugo_stats\\.json"
target = "styles\\.css"
[[build.cachebusters]]
source = "(postcss|tailwind)\\.config\\.js"
target = "css"
# 开启 Minify
[minify]
disableXML = false
minifyOutput = true
[minify.tdewolff]
[minify.tdewolff.html]
keepWhitespace = false
[minify.tdewolff.js]
keepVarNames = false
[minify.tdewolff.css]
keepCSS2 = true重新构建:
hugo -D --minify效果:
main.css: 245K → 68K (压缩率 72%)
main.js: 120K → 45K (压缩率 62%)3. 图片优化 #
问题 #
文章中的图片都是 PNG 格式,单张 500KB+。
解决方案 #
转换为 WebP 格式:
# 批量转换
find content/posts -name "*.png" -exec sh -c '
for file; do
cwebp -q 80 "$file" -o "${file%.png}.webp"
done
' sh {} +在 Markdown 中使用:
<!-- 原来 -->

<!-- 优化后 -->
效果:
单张图片:500KB PNG → 80KB WebP (压缩率 84%)
页面总大小:2.1MB → 650KB4. Nginx 配置优化 #
问题 #
默认的 Nginx 配置没有开启 Gzip 压缩和缓存。
解决方案 #
编辑 /etc/nginx/nginx.conf:
# 开启 Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript
application/x-javascript application/xml
application/javascript application/json;
gzip_disable "MSIE [1-6]\.";
# 静态资源缓存
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# HTML 不缓存
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}重新加载 Nginx:
nginx -t && systemctl reload nginx效果:
HTML 传输大小:45KB → 12KB (Gzip 压缩率 73%)
CSS 传输大小:68KB → 18KB5. CDN 加速(可选,但强烈推荐) #
问题 #
服务器在国内,但部分用户访问可能走国际线路。
解决方案 #
方案 A:Cloudflare(免费)
- 注册 Cloudflare 账号
- 添加域名
ai.mylog.vip - 修改 Nameserver 到 Cloudflare
- 开启 Auto Minify 和 Brotli 压缩
方案 B:阿里云 CDN(国内更快)
# 阿里云 CDN 配置
# 源站:47.252.1.11
# 缓存规则:
# - *.html: 不缓存
# - *.css: 缓存 30 天
# - *.js: 缓存 30 天
# - 图片:缓存 90 天效果:
国内访问延迟:80ms → 15ms
首字节时间 (TTFB):320ms → 45ms优化结果对比 #
Lighthouse 分数 #
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| Performance | 68 | 96 | +41% |
| FCP | 2.1s | 0.4s | 5.2x |
| Speed Index | 3.2s | 0.5s | 6.4x |
| LCP | 2.8s | 0.5s | 5.6x |
| TBT | 450ms | 0ms | ✅ |
加载时间 #
优化前:3.2 秒
优化后:0.5 秒
提升:6.4 倍 🚀页面大小 #
| 资源类型 | 优化前 | 优化后 | 压缩率 |
|---|---|---|---|
| HTML | 45KB | 12KB | 73% |
| CSS | 257KB | 22KB | 91% |
| JS | 120KB | 45KB | 62% |
| 图片 | 2.1MB | 350KB | 83% |
| 总计 | 2.5MB | 429KB | 83% |
配置清单(可直接复制) #
Hugo 配置 (hugo.toml)
#
[build]
[build.buildStats]
enable = true
[minify]
disableXML = false
minifyOutput = trueNginx 配置 #
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/javascript application/json;
location ~* \.(css|js|webp|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}字体加载 #
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=..."
rel="stylesheet" media="print" onload="this.media='all'">避坑指南 #
1. 字体不要太多 #
我最开始加载了 7 种字体变体,结果字体文件 400KB+。
建议:只加载需要的字重(400, 500, 600, 700)。
2. 图片用 WebP,但保留 PNG 降级 #
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.png" alt="描述">
</picture>3. 缓存别设置太长 #
HTML 文件不要设置长缓存,否则更新后用户看不到。
# HTML 不缓存
location ~* \.html$ {
expires -1;
}下一步优化方向 #
目前还有可以优化的地方:
- 懒加载:文章列表页的图片懒加载
- 预加载:关键资源预加载(
<link rel="preload">) - HTTP/3:开启 QUIC 协议
- Brotli:比 Gzip 压缩率更高
但这些优化带来的收益已经很小了(0.5s → 0.3s),优先级不高。
总结 #
核心优化点:
- ✅ 字体异步加载(FCP 2.1s → 1.2s)
- ✅ CSS/JS 压缩(257KB → 22KB)
- ✅ 图片 WebP 格式(2.1MB → 350KB)
- ✅ Nginx Gzip 压缩(传输大小减少 70%)
最终结果:3.2 秒 → 0.5 秒,提升 6.4 倍。
成本:一下午,约 3 小时。
收益:用户体验大幅提升,SEO 分数提高,跳出率降低。
工具推荐 #
- Lighthouse:性能测试(Chrome DevTools 内置)
- PageSpeed Insights:在线测试 + 优化建议
- WebPageTest:多地点测试
- cwebp:图片转换工具
最后一句:
性能优化不是一次性的工作,而是一个持续的过程。
但记住:80% 的收益来自 20% 的优化。先把大问题解决,再考虑细节。
你的博客加载时间是多少?可以留言分享一下优化经验。