从代码分割到图片懒加载的完整方案
如果你想让你的网站在 Lighthouse 测试中获得 90+ 甚至满分,那么性能优化是必不可少的。本文将分享一系列实战验证的黑科技,帮助你大幅提升页面加载速度、优化渲染性能,并轻松通过 Core Web Vitals 考核。
1. Lighthouse 评分标准解析
在开始优化之前,先了解 Lighthouse 的评分机制,主要考察:
✅ Performance(性能):FCP、LCP、TBT、CLS 等
✅ Accessibility(无障碍):HTML 语义化、ARIA 标签
✅ Best Practices(最佳实践):HTTPS、安全策略
✅ SEO(搜索引擎优化):meta 标签、结构化数据
✅ PWA(渐进式 Web 应用)(可选)
本文重点聚焦 Performance 优化,其他部分后续再单独讲解。
2. 代码优化:减少 JavaScript & CSS 阻塞
(1)代码分割(Code Splitting)
问题:打包后的 bundle.js
过大,导致主线程阻塞,影响 FCP(First Contentful Paint)。
解决方案:
- React / Vue 动态导入(懒加载组件):
const LazyComponent = React.lazy(() => import('./LazyComponent'));
- Webpack / Vite 自动代码分割:
// webpack.config.js optimization: { splitChunks: { chunks: 'all', }, }
- 路由级代码分割(Next.js / Nuxt.js):自动按路由拆分 JS。
(2)Tree Shaking 移除无用代码
确保你的项目使用 ES Modules(ESM) 并开启 sideEffects: false
:
// package.json
{
"sideEffects": false
}
Vite / Rollup / Webpack 默认支持 Tree Shaking,但需避免 import * as lodash
这种写法。
(3)预加载关键资源(Preload / Prefetch)
<!-- 关键 CSS -->
<link rel="preload" href="critical.css" as="style" />
<!-- 关键字体 -->
<link rel="preload" href="font.woff2" as="font" crossorigin />
<!-- 预取非关键资源 -->
<link rel="prefetch" href="next-page.js" as="script" />
3. 图片优化:懒加载 & 现代格式
(1)图片懒加载(Lazy Loading)
<img src="placeholder.jpg" loading="lazy" alt="..." />
或使用 Intersection Observer API 实现更精细控制:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
(2)使用现代图片格式(WebP / AVIF)
<picture>
<source srcset="image.avif" type="image/avif" />
<source srcset="image.webp" type="image/webp" />
<img src="image.jpg" alt="..." />
</picture>
推荐工具:
- Squoosh(在线压缩)
- Sharp(Node.js 批量转换)
(3)CDN + 响应式图片
<img
srcset="small.jpg 480w, medium.jpg 768w, large.jpg 1200w"
sizes="(max-width: 600px) 480px, (max-width: 1024px) 768px, 1200px"
src="fallback.jpg"
alt="..."
/>
4. 字体优化:避免 FOIT / FOUT
问题:自定义字体加载慢,导致 布局偏移(CLS) 或 空白文本(FOIT)。
解决方案:
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* 先显示后备字体,再替换 */
}
进阶方案:
- 预加载字体(
<link rel="preload" as="font" crossorigin>
) - 使用
font-face observer
检测字体加载状态
5. 服务端优化:SSR / Edge Cache
(1)启用 HTTP/2 + Brotli 压缩
# Nginx 配置
gzip on;
gzip_types text/css application/javascript;
brotli on;
brotli_types text/css application/javascript;
(2)静态资源缓存策略
location ~* \.(js|css|png|jpg|jpeg|gif|ico|webp|avif)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
(3)Edge CDN(Vercel / Cloudflare)
- Vercel:自动优化静态资源
- Cloudflare:开启
Auto Minify
+Rocket Loader
6. 终极优化:PRPL 模式
Google 推荐的 PRPL 架构:
- Push(推送关键资源)
- Render(尽早渲染首屏)
- Pre-cache(预缓存剩余资源)
- Lazy-load(懒加载非关键资源)
适用场景:
- Next.js / Nuxt.js(自动优化)
- PWA + Workbox(Service Worker 缓存策略)
7. 实测效果
优化前后对比(以 Next.js 为例):
指标 | 优化前 | 优化后 |
---|---|---|
LCP | 2.8s | 0.9s |
CLS | 0.25 | 0.02 |
TBT | 450ms | 120ms |
Lighthouse 总分 | 72 | 98 |
总结
✅ 代码优化:代码分割 + Tree Shaking + 预加载
✅ 图片优化:懒加载 + WebP/AVIF + 响应式
✅ 字体优化:font-display: swap
+ 预加载
✅ 服务端优化:HTTP/2 + Brotli + CDN
✅ 终极方案:PRPL 架构 + PWA
立即测试你的网站:
👉 Google Lighthouse
👉 WebPageTest
如果你有更酷的优化技巧,欢迎在评论区分享! 🚀