性能优化-加载策略
资源加载优化
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-Match2. 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 → 阻塞解析优化原则
- 内联关键 CSS — 首屏渲染所需样式直接内联
- async / defer — 非关键 JS 延迟加载
- 减少首屏资源 — 只加载视口内必要内容
- 预加载关键资源 — 使用
<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>
Cao Note