折腾侠
技术教程

前端性能优化实战 - 让你的网站飞起来

网站太慢?本文详解前端性能优化全流程和实战技巧。

折腾侠
2026/03/15 发布
32约 6 分钟864 字 / 751 词00

前端性能优化实战 - 让你的网站飞起来

网站太慢?本文详解前端性能优化全流程和实战技巧。

📋 前言

网站速度直接影响用户体验和转化率。

数据说话:

  • 页面加载超过 3 秒,53% 用户会离开
  • 每慢 1 秒,转化率下降 7%
  • Google 将页面速度作为排名因素

优化目标:

  • 首屏加载 < 1.5 秒
  • 完全加载 < 3 秒
  • Lighthouse 分数 > 90

本文从测量到优化,全面讲解前端性能优化。


🎯 性能指标

Core Web Vitals

指标全称目标值
LCPLargest Contentful Paint< 2.5s
FIDFirst Input Delay< 100ms
CLSCumulative Layout Shift< 0.1

其他关键指标

指标说明目标值
FCPFirst Contentful Paint< 1.5s
TTITime to Interactive< 3.5s
TBTTotal 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. 其他优化

最后建议:

性能优化是持续过程,不是一次性任务。

测量 → 优化 → 监控 → 再优化


你有什么性能优化经验? 欢迎在评论区分享!👇

📚 参考资源

分享到:

如果这篇文章对你有帮助,欢迎请作者喝杯咖啡 ☕

加载评论中...