用 PageSpeed 测首页,移动端 4.2 秒,分数 38。花了两周一点点优化到 1.1 秒,分数 92。记录一下真正有效的几件事。
先量,别猜
Chrome DevTools 的 Lighthouse 会给出具体指标:
FCP 首次内容绘制
LCP 最大内容绘制(一般是首图或标题)
TBT 总阻塞时间(JS 执行)
CLS 布局偏移(图片没写尺寸导致跳动)
我最初的瓶颈是 LCP 4.1 秒,主因是首图 1.2MB 且没有预加载。
第一件:图片
这一项收益最大,占到总提升的 60%。
- 统一压缩到 1200px 宽,质量 80,格式转 WebP
- 加
width/height属性,避免 CLS - 首图加
fetchpriority=high,不让它排在最后加载 - 非首屏图片
loading=lazy
<img src="/img/cover.webp" width="1200" height="630"
alt="封面" fetchpriority="high">
<img src="/img/other.webp" loading="lazy" width="800" height="450" alt="">
一张 1.2MB 的 jpg 压成 90KB 的 webp,LCP 直接降了 2 秒。
第二件:字体
之前用了 Google Fonts 的中文字体,一个 woff2 几 MB,还阻塞渲染。
改成系统字体栈:
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
"PingFang SC", "Microsoft YaHei", sans-serif;
零请求、零延迟,视觉上几乎没差别。如果一定要用自定义字体,用 font-display: swap 并只加载需要的字重。
第三件:JS 和 CSS
- 删掉不用的插件脚本(主题里带的轮播、动画库)
- 非关键 JS 加
defer - 关键 CSS 内联到
<head>,其余异步加载
<link rel="preload" href="/style.css" as="style" onload="this.rel='stylesheet'">
原来页面有 60 多个请求,减到 12 个,TBT 从 800ms 降到 120ms。
第四件:缓存
location ~* \.(jpg|png|webp|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
配合文件名带 hash(style.a1b2c3.css),内容变了文件名就变,可以放心长缓存。
HTML 不缓存或只缓存 60 秒,保证内容及时更新。
第五件:传输层
- 开 HTTP/2(多路复用,省掉队头阻塞)
- 开 Brotli 压缩(比 gzip 小 15~20%)
- 上 CDN,静态资源就近返回
brotli on;
brotli_comp_level 5;
brotli_types text/html text/css application/javascript application/json;
效果
| 指标 | 优化前 | 优化后 |
|---|---|---|
| LCP | 4.1s | 0.9s |
| FCP | 2.8s | 0.7s |
| TBT | 800ms | 120ms |
| 请求数 | 63 | 12 |
| 页面大小 | 2.3MB | 320KB |
心得
优化顺序很重要:图片 > 字体 > JS > 缓存 > 传输。前两项做完通常就解决大半问题,后面的收益递减。
不要一上来就折腾「代码分割」「预渲染」这些高级手段,先把图片压了。
- THE END -
最后修改:2025年6月14日
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://mi-blog.cn/archives/696
共有 0 条评论