75 - 前端性能优化实战手册

适用人群:前端开发者
难度:中等
预计学习时间:8-12小时

核心性能指标(Core Web Vitals)

指标全称目标值说明
LCPLargest Contentful Paint< 2.5s最大内容渲染时间
FIDFirst Input Delay< 100ms首次输入延迟
CLSCumulative Layout Shift< 0.1累计布局偏移
INPInteraction to Next Paint< 200ms交互响应时间
TTFBTime to First Byte< 800ms首字节时间
FCPFirst Contentful Paint< 1.8s首次内容渲染

优化策略清单

1. 资源优化

# 图片优化
# 使用WebP/AVIF格式
<picture>
  <source srcset="image.avif" type="image/avif">
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="..." loading="lazy" decoding="async">
</picture>

# Next.js图片优化
import Image from 'next/image'
<Image src="/photo.jpg" width={800} height={600} alt="..." priority />

# 代码分割
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>Loading...</p>,
  ssr: false
})

# Tree Shaking
# 确保使用ESM导入
import { debounce } from 'lodash-es'  // 好
import _ from 'lodash'                 // 坏(整个lodash)

2. 网络优化

# Nginx缓存配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

# 开启Gzip/Brotli压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;

# HTTP/2
listen 443 ssl http2;

# 预加载关键资源
<link rel="preload" href="/fonts/main.woff2" as="font" crossorigin>
<link rel="preconnect" href="https://api.example.com">

3. 渲染优化

// React性能优化
import { memo, useMemo, useCallback } from 'react'

// memo避免不必要的重渲染
const ExpensiveList = memo(function ExpensiveList({ items, onSelect }) {
  return items.map(item => (
    <div key={item.id} onClick={() => onSelect(item.id)}>
      {item.name}
    </div>
  ))
})

// useMemo缓存计算结果
function FilteredList({ items, query }) {
  const filtered = useMemo(
    () => items.filter(item => item.name.includes(query)),
    [items, query]
  )
  return <ExpensiveList items={filtered} />
}

// useCallback缓存函数引用
function Parent() {
  const [selected, setSelected] = useState(null)
  const handleSelect = useCallback((id) => setSelected(id), [])
  return <ExpensiveList items={items} onSelect={handleSelect} />
}

// 虚拟列表(大量数据)
import { useVirtualizer } from '@tanstack/react-virtual'

function VirtualList({ items }) {
  const parentRef = useRef(null)
  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50
  })
  return (
    <div ref={parentRef} style={{ height: '400px', overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize() }}>
        {virtualizer.getVirtualItems().map(vItem => (
          <div key={vItem.key} style={{
            position: 'absolute',
            top: vItem.start,
            height: vItem.size,
            width: '100%'
          }}>
            {items[vItem.index].name}
          </div>
        ))}
      </div>
    </div>
  )
}

4. CSS优化

/* 避免昂贵的选择器 */
/* 坏 */
div > ul > li > a > span { }
/* 好 */
.nav-link-text { }

/* 使用contain优化重排 */
.card {
  contain: layout style paint;
}

/* 使用content-visibility优化屏幕外元素 */
.below-fold {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px;
}

/* 减少重绘 */
.animated-element {
  will-change: transform;
  transform: translateZ(0);  /* 创建合成层 */
}


性能检测工具

工具用途
Lighthouse综合性能评估
PageSpeed Insights在线性能分析
Chrome DevTools Performance运行时性能分析
WebPageTest多地点测试
bundlephobia包体积检查
webpack-bundle-analyzer打包分析

检查清单

□ 图片使用WebP/AVIF格式
□ 图片懒加载
□ 关键CSS内联
□ JS代码分割
□ 字体子集化
□ 开启Gzip/Brotli压缩
□ 使用CDN
□ 设置合理的缓存策略
□ 减少第三方脚本
□ 使用Intersection Observer
□ 避免布局偏移
□ 服务端渲染/静态生成

返回首页