前端性能优化有哪些常见手段?
加载优化
1. 减少请求
- 合并文件(JS/CSS 打包)
- 雪碧图 → CSS 图标/字体图标 → SVG sprite
- 内联关键 CSS(Critical CSS)
2. 压缩
- Gzip / Brotli 压缩
- 图片压缩(WebP > JPEG, AVIF 更优)
- 代码压缩(Terser、cssnano)
3. 缓存
- 强缓存 + 协商缓存
- 文件名哈希(contenthash)
- Service Worker 离线缓存
4. 按需加载
- 路由懒加载
- 组件懒加载
- 图片懒加载
- 动态 import()
// 路由懒加载
const Home = lazy(() => import('./Home'))
// 图片懒加载
<img loading="lazy" src="image.jpg" />
// 动态导入
const module = await import('./heavy-module')5. 预加载
<!-- 预加载关键资源 -->
<link rel="preload" href="/critical.js" as="script">
<link rel="preload" href="/font.woff2" as="font" crossorigin>
<!-- 预连接 -->
<link rel="preconnect" href="https://cdn.example.com">
<link rel="dns-prefetch" href="https://cdn.example.com">
<!-- 预获取(空闲时) -->
<link rel="prefetch" href="/next-page.js">渲染优化
1. CSS 优化
- 关键 CSS 内联到
<head> - 非关键 CSS 异步加载
- 避免使用
@import(阻塞渲染)
2. JS 优化
defer:不阻塞解析,DOMContentLoaded 前执行async:不阻塞解析,下载完立即执行- 避免长任务(> 50ms)
3. 减少重排重绘
- 使用 transform/opacity 做动画
- 批量 DOM 操作
- 使用 will-change
4. 虚拟列表
// react-window
import { FixedSizeList } from 'react-window'
<FixedSizeList height={600} itemCount={10000} itemSize={35}>
{Row}
</FixedSizeList>图片优化
<!-- 响应式图片 -->
<img src="small.jpg"
srcset="medium.jpg 768w, large.jpg 1200w"
sizes="(max-width: 768px) 100vw, 50vw">
<!-- 现代格式 -->
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg">
</picture>构建优化
// Vite 构建
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
utils: ['lodash-es', 'dayjs']
}
}
},
minify: 'terser',
cssCodeSplit: true
}
})性能指标
| 指标 | 含义 | 目标 |
|---|---|---|
| FCP | 首次内容绘制 | < 1.8s |
| LCP | 最大内容绘制 | < 2.5s |
| FID | 首次输入延迟 | < 100ms |
| CLS | 累积布局偏移 | < 0.1 |
| TTI | 可交互时间 | < 3.8s |
检测工具
- Chrome DevTools → Performance / Lighthouse
- WebPageTest
- Core Web Vitals(Search Console)