如何提高前端应用的性能?

33 阅读1分钟
# 前端性能优化实战指南

## 核心优化策略

### 1. 资源加载优化
- **代码分割**:使用Webpack的SplitChunksPlugin进行第三方库分离
```javascript
// webpack.config.js
optimization: {
  splitChunks: {
    chunks: 'all',
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors'
      }
    }
  }
}
  • 预加载关键资源
<link rel="preload" href="critical.css" as="style">
<link rel="prefetch" href="next-page.js" as="script">
  • 图片优化
# 使用Sharp进行图片压缩
sharp(inputBuffer)
  .webp({ quality: 80 })
  .toBuffer()

2. 渲染性能优化

  • 避免强制同步布局
// 错误示例(导致布局抖动)
function resizeAll() {
  for (let i = 0; i < boxes.length; i++) {
    boxes[i].style.width = boxes[i].offsetWidth + 10 + 'px';
  }
}

// 正确做法(使用requestAnimationFrame)
function resizeAll() {
  requestAnimationFrame(() => {
    const widths = boxes.map(box => box.offsetWidth);
    widths.forEach((w, i) => {
      boxes[i].style.width = w + 10 + 'px';
    });
  });
}
  • CSS优化技巧
/* 启用GPU加速 */
.transform-element {
  will-change: transform;
  transform: translateZ(0);
}

/* 简化选择器层级 */
.card > .title {}  /* 避免 */
.card-title {}     /* 推荐 */

3. JavaScript优化

  • 防抖节流实现
const throttle = (fn, delay) => {
  let lastCall = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastCall < delay) return;
    lastCall = now;
    return fn(...args);
  };
};

window.addEventListener('resize', throttle(updateLayout, 200));
  • 虚拟滚动实现
function VirtualList({ items, itemHeight, containerHeight }) {
  const [scrollTop, setScrollTop] = useState(0);
  const startIdx = Math.floor(scrollTop / itemHeight);
  const visibleItems = items.slice(startIdx, startIdx + Math.ceil(containerHeight / itemHeight));

  return (
    <div onScroll={e => setScrollTop(e.target.scrollTop)}>
      <div style={{ height: `${items.length * itemHeight}px` }}>
        {visibleItems.map((item, i) => (
          <div key={i} style={{ height: `${itemHeight}px` }}>
            {item}
          </div>
        ))}
      </div>
    </div>
  );
}

4. 缓存策略

  • Service Worker缓存
// sw.js
self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open('v1').then(cache => {
      return cache.addAll([
        '/',
        '/styles/main.css',
        '/scripts/main.js'
      ]);
    })
  );
});

self.addEventListener('fetch', (e) => {
  e.respondWith(
    caches.match(e.request).then(response => {
      return response || fetch(e.request);
    })
  );
});
  • HTTP缓存头设置
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
  expires 1y;
  add_header Cache-Control "public, no-transform";
}

性能监控方案

// 使用Performance API监控关键指标
const measurePerf = () => {
  const [navigation] = performance.getEntriesByType('navigation');
  console.log({
    TTFB: navigation.responseStart - navigation.requestStart,
    FCP: performance.getEntriesByName('first-contentful-paint')[0].startTime,
    DOMReady: navigation.domComplete - navigation.domInteractive
  });
};

window.addEventListener('load', measurePerf);

进阶优化技巧

  1. WebAssembly应用:将计算密集型任务移植到Wasm模块
  2. Web Worker使用:将长时间运行的任务移出主线程
  3. CSS Containment:限制浏览器重绘范围
.widget {
  contain: layout paint style;
}

工具推荐