Skip to content

性能优化-加载策略 ​

资源加载优化 ​

1. 代码分割 ​

js
// React.lazy + Suspense
const Dashboard = React.lazy(() => import('./Dashboard'))

// Vite 动态导入自动分割
const charts = await import('./charts')

// Webpack import()
import(/* webpackChunkName: "admin" */ './admin')
// React.lazy + Suspense
const Dashboard = React.lazy(() => import('./Dashboard'))

// Vite 动态导入自动分割
const charts = await import('./charts')

// Webpack import()
import(/* webpackChunkName: "admin" */ './admin')

2. 预加载策略 ​

html
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="//api.example.com">

<!-- 预连接 -->
<link rel="preconnect" href="//fonts.googleapis.com">

<!-- 预加载关键资源 -->
<link rel="preload" href="/fonts/icon.woff2" as="font" crossorigin>

<!-- 预获取(空闲时加载) -->
<link rel="prefetch" href="/pages/dashboard.js">

<!-- 预渲染(慎用,耗内存) -->
<link rel="prerender" href="/next-page">
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="//api.example.com">

<!-- 预连接 -->
<link rel="preconnect" href="//fonts.googleapis.com">

<!-- 预加载关键资源 -->
<link rel="preload" href="/fonts/icon.woff2" as="font" crossorigin>

<!-- 预获取(空闲时加载) -->
<link rel="prefetch" href="/pages/dashboard.js">

<!-- 预渲染(慎用,耗内存) -->
<link rel="prerender" href="/next-page">

3. 图片优化 ​

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

<!-- 懒加载 -->
<img src="image.jpg" loading="lazy" decoding="async">

<!-- 响应式图片 -->
<img
  srcset="image-320w.jpg 320w, image-640w.jpg 640w, image-1280w.jpg 1280w"
  sizes="(max-width: 320px) 280px, (max-width: 640px) 600px, 1200px"
  src="image-1280w.jpg"
>

<!-- 使用 CSS content-visibility -->
.lazy-section {
  content-visibility: auto;
  contain-intrinsic-size: 500px;
}
<!-- WebP 格式 -->
<picture>
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="">
</picture>

<!-- 懒加载 -->
<img src="image.jpg" loading="lazy" decoding="async">

<!-- 响应式图片 -->
<img
  srcset="image-320w.jpg 320w, image-640w.jpg 640w, image-1280w.jpg 1280w"
  sizes="(max-width: 320px) 280px, (max-width: 640px) 600px, 1200px"
  src="image-1280w.jpg"
>

<!-- 使用 CSS content-visibility -->
.lazy-section {
  content-visibility: auto;
  contain-intrinsic-size: 500px;
}

4. 字体优化 ​

css
/* 字体预加载 + 回退 */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap; /* 先用系统字体,加载后替换 */
}

/* 子集化字体 */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF; /* 只包含 ASCII */
}
/* 字体预加载 + 回退 */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap; /* 先用系统字体,加载后替换 */
}

/* 子集化字体 */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF; /* 只包含 ASCII */
}

网络优化 ​

1. HTTP 缓存 ​

# 强缓存(浏览器直接使用,不请求服务器)
Cache-Control: public, max-age=31536000, immutable

# 协商缓存(请求服务器验证)
Last-Modified / If-Modified-Since
ETag / If-None-Match
# 强缓存(浏览器直接使用,不请求服务器)
Cache-Control: public, max-age=31536000, immutable

# 协商缓存(请求服务器验证)
Last-Modified / If-Modified-Since
ETag / If-None-Match

2. CDN 加速 ​

  • 静态资源部署到 CDN,减小服务器压力
  • 多地域节点就近访问
  • 配合 immutable 缓存策略

3. HTTP/2 HTTP/3 ​

  • 多路复用(避免连接数限制)
  • 服务器推送(Server Push)
  • 头部压缩(HPACK / QPACK)
  • 二进制分帧

4. 资源压缩 ​

js
// nginx gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_comp_level 6;
gzip_min_length 1000;

// Brotli(比 gzip 更好)
brotli on;
brotli_types text/plain text/css application/javascript;
// nginx gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_comp_level 6;
gzip_min_length 1000;

// Brotli(比 gzip 更好)
brotli on;
brotli_types text/plain text/css application/javascript;

关键渲染路径 (CRP) ​

HTML → DOM Tree
        ↓
CSS  → CSSOM Tree  → Render Tree → Layout → Paint
        ↑
JS   → 阻塞解析
HTML → DOM Tree
        ↓
CSS  → CSSOM Tree  → Render Tree → Layout → Paint
        ↑
JS   → 阻塞解析

优化原则 ​

  1. 内联关键 CSS — 首屏渲染所需样式直接内联
  2. async / defer — 非关键 JS 延迟加载
  3. 减少首屏资源 — 只加载视口内必要内容
  4. 预加载关键资源 — 使用 <link rel="preload">
html
<!-- 推荐:defer 按顺序执行 -->
<script src="app.js" defer></script>

<!-- 推荐:async 加载完立即执行(不保证顺序) -->
<script src="analytics.js" async></script>

<!-- 不推荐:同步阻塞 -->
<script src="script.js"></script>
<!-- 推荐:defer 按顺序执行 -->
<script src="app.js" defer></script>

<!-- 推荐:async 加载完立即执行(不保证顺序) -->
<script src="analytics.js" async></script>

<!-- 不推荐:同步阻塞 -->
<script src="script.js"></script>