前端工程Technical Deep Dive

前端性能优化 —— 网络优化、缓存策略与 CDN

发布时间2026/03/29
分类前端工程
预计阅读2 分钟
作者吴长龙
*

网络优化概述

01.内容

网络优化概述

前端性能优化中,网络请求往往是最大的瓶颈。减少请求次数、缩短请求时间、减轻服务器压力,是前端工程师的核心技能。

HTTP/1.1 的问题

#### 1. 队头阻塞

code snippetcode
请求 1: ======>
请求 2:        ======>
请求 3:             ======>

HTTP/1.1 只有在一个请求响应完成后,才能发起下一个请求。

#### 2. 重复发送

code snippetcode
每个请求都要携带:
- Cookie
- 认证头
- 相同的域名头部

#### 3. 资源竞争

code snippetcode
浏览器限制同一域名并发数:6 个
资源多时只能排队等待

HTTP/2 革命

#### 多路复用

code snippetcode
单一连接,多个流并行:
流 1: ====>
流 2:   ====>
流 3:     ====>
nginx snippetnginx
# Nginx 配置 HTTP/2
server {
    listen 443 ssl http2;
    ssl_certificate cert.pem;
    ssl_certificate_key key.pem;
}

#### 二进制分帧

code snippetcode
应用层: 消息 (HTTP 语义)
传输层: 分帧 (HTTP/2 逻辑)

#### 首部压缩

code snippetcode
HPACK 算法:
- 静态表 (常见首部)
- 动态表 (当前连接)
- 霍夫曼编码

#### 服务器推送

nginx snippetnginx
# Nginx 推送
location / {
    http2_push /css/style.css;
    http2_push /js/app.js;
}

HTTP/3 (QUIC)

javascript snippetjavascript
// HTTP/3 优势:
// 1. 基于 UDP,无队头阻塞
// 2. 0-RTT 握手
// 3. 连接迁移 (IP 变化无感)

缓存策略

#### 缓存类型

类型位置作用
Service Worker浏览器离线缓存
Memory Cache内存页面生命周期
Disk Cache磁盘持久缓存
Push CacheHTTP/2服务器推送

#### 缓存控制

javascript snippetjavascript
// 响应头
Cache-Control: max-age=3600        // 3600 秒内有效
Cache-Control: no-cache            // 每次验证
Cache-Control: no-store            // 不缓存
Cache-Control: private             // 只浏览器缓存
Cache-Control: public              // 可被 CDN 缓存

// 组合使用
Cache-Control: max-age=31536000, immutable
Cache-Control: no-cache, must-revalidate

#### 缓存策略实践

javascript snippetjavascript
// 1. 永不变化的资源:长期缓存
Cache-Control: max-age=31536000, immutable

// 2. 变化的资源:版本化
// style.css?v=1.0.0
// style.css.abc123.css (内容哈希)

// 3. HTML:总是验证
Cache-Control: no-cache, must-revalidate

// 4. API:视情况
Cache-Control: no-cache  // 每次获取最新

#### 缓存策略图

code snippetcode
浏览器请求 → Memory Cache → Disk Cache → 服务器
     ↓              ↓            ↓
   直接返回      直接返回     验证后返回
   (无请求)      (无请求)     (304)/新内容

CDN 优化

#### CDN 原理

code snippetcode
用户 → CDN 边缘节点 → 源站
   ↓              ↓
  命中           回源

#### CDN 配置最佳实践

javascript snippetjavascript
// 1. 开启压缩
Accept-Encoding: gzip, br, zstd

// 2. 静态资源使用 CDN
https://cdn.example.com/js/app.js

// 3. 跨域配置
Access-Control-Allow-Origin: *

// 4. 缓存时间
Cache-Control: public, max-age=31536000

#### 预热与刷新

javascript snippetjavascript
// CDN 预热:提前将资源推送到边缘节点
// 刷新:清除指定 URL 的缓存
POST /cdn/refresh
{
  "urls": ["https://cdn.example.com/js/app.js"]
}

资源优化

#### 1. 图片优化

html snippethtml
<!-- 现代格式 -->
<picture>
  <source srcset="image.avif" type="image/avif">
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="...">
</picture>

<!-- 响应式图片 -->
<img 
  srcset="img-320.jpg 320w,
          img-640.jpg 640w,
          img-1024.jpg 1024w"
  sizes="(max-width: 640px) 100vw, 640px"
  src="img-640.jpg"
>

#### 2. 字体优化

html snippethtml
<!-- 预加载关键字体 -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

<!-- 使用 font-display -->
<style>
  @font-face {
    font-family: 'MyFont';
    src: url('font.woff2') format('woff2');
    font-display: swap; /* 加载期间显示备用字体 */
  }
</style>

#### 3. CSS/JS 优化

html snippethtml
<!-- 关键 CSS 内联 -->
<style>
  /* 只包含首屏需要的样式 */
</style>

<!-- 非关键 CSS 异步加载 -->
<link rel="preload" as="style" href="styles.css" 
      onload="this.onload=null;this.rel='stylesheet'">

<!-- JS 延迟加载 -->
<script defer src="app.js"></script>
<script async src="analytics.js"></script>

资源合并与拆分

#### 合并 vs 拆分

策略优点缺点
合并减少请求数缓存失效、带宽浪费
拆分精细缓存、按需加载请求数增加

#### 最佳实践

javascript snippetjavascript
// Vite 配置
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        // 手动拆分 chunk
        manualChunks: {
          'vendor': ['react', 'react-dom'],
          'utils': ['lodash', 'axios'],
          'ui': ['antd', '@mui/material']
        }
      }
    }
  }
});

Service Worker 缓存

javascript snippetjavascript
// sw.js
const CACHE_NAME = 'v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/scripts/app.js'
];

// 安装
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(urlsToCache))
  );
});

// 拦截请求
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        // 缓存命中返回缓存,否则请求网络
        return response || fetch(event.request);
      })
  );
});

总结

优化方向具体措施
协议升级HTTP/2、HTTP/3
缓存策略合理设置 Cache-Control
CDN静态资源托管、边缘计算
资源优化图片格式、代码压缩
请求优化合并、拆分、预加载

网络优化是前端性能的基础,需要持续关注和迭代。