前端性能优化实战 - 让你的网站飞起来
网站太慢?本文详解前端性能优化全流程和实战技巧。
折
折腾侠
2026/03/15 发布
32约 6 分钟864 字 / 751 词00
前端性能优化实战 - 让你的网站飞起来
网站太慢?本文详解前端性能优化全流程和实战技巧。
📋 前言
网站速度直接影响用户体验和转化率。
数据说话:
- 页面加载超过 3 秒,53% 用户会离开
- 每慢 1 秒,转化率下降 7%
- Google 将页面速度作为排名因素
优化目标:
- 首屏加载 < 1.5 秒
- 完全加载 < 3 秒
- Lighthouse 分数 > 90
本文从测量到优化,全面讲解前端性能优化。
🎯 性能指标
Core Web Vitals
| 指标 | 全称 | 目标值 |
|---|---|---|
| LCP | Largest Contentful Paint | < 2.5s |
| FID | First Input Delay | < 100ms |
| CLS | Cumulative Layout Shift | < 0.1 |
其他关键指标
| 指标 | 说明 | 目标值 |
|---|---|---|
| FCP | First Contentful Paint | < 1.5s |
| TTI | Time to Interactive | < 3.5s |
| TBT | Total Blocking Time | < 200ms |
测量工具
Bash
# Chrome DevTools
# Lighthouse 面板 → 运行测试
# PageSpeed Insights
https://pagespeed.web.dev/
# WebPageTest
https://www.webpagetest.org/
# Chrome User Experience Report
https://chromeuxreport.dev/
🚀 优化策略
1. 减少 HTTP 请求
问题:
- 每个资源都需要 HTTP 请求
- 请求越多,加载越慢
解决方案:
JavaScript
// ✅ 代码分割(按需加载)
const Chart = () => import('./Chart');
// ✅ 合并小文件
// 多个小 CSS 合并为一个
// ✅ 使用雪碧图
.icon {
background-image: url('sprites.png');
}
// ✅ 内联关键 CSS
<style>
/* 首屏关键样式 */
</style>
2. 启用压缩
Gzip 压缩:
Nginx
# Nginx 配置
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
Brotli 压缩(推荐):
Nginx
# Nginx + Brotli
brotli on;
brotli_types text/plain text/css application/json application/javascript;
brotli_comp_level 6;
压缩效果:
原始文件:100KB
Gzip 后:30KB(减少 70%)
Brotli 后:25KB(减少 75%)
3. 使用 CDN
为什么用 CDN?
- 就近访问,降低延迟
- 分担源站压力
- 自带缓存和压缩
主流 CDN:
| 服务商 | 特点 | 价格 |
|---|---|---|
| Cloudflare | 免费,全球节点 | 免费 |
| 阿里云 CDN | 国内速度快 | 按量付费 |
| 腾讯云 CDN | 国内覆盖广 | 按量付费 |
| AWS CloudFront | 全球覆盖 | 按量付费 |
4. 图片优化
问题:
- 图片通常占页面 60%+ 体积
解决方案:
HTML
<!-- ✅ 使用现代格式 -->
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="description">
</picture>
<!-- ✅ 响应式图片 -->
<img srcset="small.jpg 480w,
medium.jpg 768w,
large.jpg 1200w"
sizes="(max-width: 600px) 480px,
(max-width: 900px) 768px,
1200px"
src="large.jpg" alt="description">
<!-- ✅ 懒加载 -->
<img src="image.jpg" loading="lazy" alt="description">
图片压缩工具:
- TinyPNG
- Squoosh
- ImageOptim
5. 代码优化
JavaScript 优化:
JavaScript
// ✅ 避免阻塞渲染
<script src="app.js" defer></script>
<script src="analytics.js" async></script>
// ✅ 代码分割
const Dashboard = lazy(() => import('./Dashboard'));
// ✅ 移除未使用代码
// 使用 Tree Shaking
// ✅ 避免长任务
// 使用 Web Workers 处理计算密集型任务
CSS 优化:
CSS
/* ✅ 避免选择器过深 */
.header .nav .item .link { } /* 不好 */
.nav-link { } /* 好 */
/* ✅ 移除未使用 CSS */
/* 使用 PurgeCSS */
/* ✅ 关键 CSS 内联 */
<style>
/* 首屏样式 */
</style>
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
6. 缓存策略
浏览器缓存:
Nginx
# 静态资源缓存 1 年
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# HTML 不缓存
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
Service Worker 缓存:
JavaScript
// 缓存策略
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
7. 预加载和预连接
HTML
<!-- 预加载关键资源 -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="preload" href="critical.css" as="style">
<!-- 预连接第三方域名 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://analytics.com">
<!-- 预取下一页 -->
<link rel="prefetch" href="/next-page.html">
8. 渲染优化
避免布局抖动:
JavaScript
// ❌ 不好 - 多次读取 offsetHeight
for (let i = 0; i < items.length; i++) {
items[i].style.height = items[i].offsetHeight + 10 + 'px';
}
// ✅ 好 - 批量读取
const heights = items.map(item => item.offsetHeight);
items.forEach((item, i) => {
item.style.height = heights[i] + 10 + 'px';
});
使用 CSS 动画:
CSS
/* ✅ 使用 transform 和 opacity */
.fade-in {
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* ❌ 避免动画 width/height/top/left */
💡 框架优化
React 优化
JavaScript
// ✅ 使用 React.memo
const MemoizedComponent = React.memo(Component);
// ✅ 使用 useMemo
const expensiveValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
// ✅ 使用 useCallback
const handleClick = useCallback(() => {
doSomething(a, b);
}, [a, b]);
// ✅ 代码分割
const LazyComponent = lazy(() => import('./LazyComponent'));
Vue 优化
JavaScript
// ✅ 使用 v-once
<span v-once>不变化的内容</span>
// ✅ 使用 v-show 代替 v-if(频繁切换)
<div v-show="visible">内容</div>
// ✅ 列表添加 key
<div v-for="item in items" :key="item.id">{{ item.name }}</div>
// ✅ 异步组件
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
);
⚡ 实战检查清单
加载性能
Markdown
□ 启用 Gzip/Brotli 压缩
□ 使用 CDN 分发静态资源
□ 图片使用 WebP 格式
□ 图片懒加载
□ 代码分割和按需加载
□ 关键 CSS 内联
□ 预加载关键资源
运行时性能
Markdown
□ 避免长任务(> 50ms)
□ 使用 requestAnimationFrame
□ 防抖和节流
□ 虚拟列表(长列表)
□ Web Workers(计算密集型)
□ 避免强制同步布局
缓存策略
Markdown
□ 设置合理的 Cache-Control
□ 使用 Service Worker
□ 静态资源指纹化
□ API 响应缓存
🎯 优化效果对比
优化前
页面大小:3.5MB
请求数:85 个
加载时间:5.2s
Lighthouse:45 分
优化后
页面大小:800KB
请求数:25 个
加载时间:1.8s
Lighthouse:95 分
优化手段
1. 图片压缩和 WebP:-60%
2. 代码分割:-40%
3. 启用压缩:-70%
4. 移除未使用代码:-30%
5. CDN 加速:-50%
🎁 总结
优化原则:
✅ 测量先行(不要盲目优化)
✅ 优化关键路径
✅ 渐进式加载
✅ 缓存一切可缓存的
✅ 持续监控
优先顺序:
1. 图片优化(效果最明显)
2. 启用压缩
3. 使用 CDN
4. 代码分割
5. 缓存策略
6. 其他优化
最后建议:
性能优化是持续过程,不是一次性任务。
测量 → 优化 → 监控 → 再优化
你有什么性能优化经验? 欢迎在评论区分享!👇