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

144 阅读2分钟
# 前端性能优化实战指南

## 1. 资源加载优化

### 1.1 代码压缩与合并
```javascript
// webpack配置示例
module.exports = {
  optimization: {
    minimize: true,  // 开启代码压缩
    splitChunks: {
      chunks: 'all'  // 代码分割
    }
  }
}
  • 使用Webpack/Rollup等工具进行代码压缩
  • 合理配置代码分割(SplitChunks)
  • 图片使用WebP格式并压缩

1.2 资源预加载

<link rel="preload" href="critical.css" as="style">
<link rel="prefetch" href="next-page.js" as="script">
  • 关键资源使用preload
  • 非关键资源使用prefetch
  • 合理使用dns-prefetch

2. 渲染性能优化

2.1 减少重排重绘

// 批量DOM操作
const fragment = document.createDocumentFragment();
items.forEach(item => {
  fragment.appendChild(createItemElement(item));
});
container.appendChild(fragment);
  • 使用transform代替top/left动画
  • 避免频繁读写DOM属性
  • 使用will-change提示浏览器

2.2 虚拟列表优化

// React示例
import { FixedSizeList } from 'react-window';

<List 
  height={600}
  itemCount={1000}
  itemSize={35}
  width={300}
>
  {Row}
</List>
  • 大数据列表使用虚拟滚动
  • 按需渲染可视区域内容
  • 避免全量DOM更新

3. JavaScript优化

3.1 代码拆分

// 动态导入
const module = await import('./module.js');
// React懒加载
const LazyComponent = React.lazy(() => import('./Component'));
  • 路由级代码拆分
  • 组件级懒加载
  • 按需加载第三方库

3.2 防抖节流

// 防抖函数
function debounce(fn, delay) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, arguments), delay);
  };
}
  • 高频事件使用防抖/节流
  • 避免频繁触发重渲染
  • 合理使用requestIdleCallback

4. 缓存策略

4.1 合理使用缓存

Cache-Control: public, max-age=31536000
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 静态资源设置长期缓存
  • 使用Service Worker缓存策略
  • 实现增量更新机制

4.2 数据缓存

// 使用SWR进行数据缓存
import useSWR from 'swr';

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher);
  // ...
}
  • 接口数据合理缓存
  • 避免重复请求相同数据
  • 实现本地数据持久化

5. 监控与持续优化

5.1 性能指标监控

// 使用web-vitals库
import { getCLS, getFID, getLCP } from 'web-vitals';

getCLS(console.log);
getFID(console.log);
getLCP(console.log);
  • 监控核心Web指标
  • 建立性能基线
  • 设置性能预算

5.2 性能分析工具

  • Chrome DevTools Performance面板
  • Lighthouse自动化测试
  • WebPageTest深度分析

6. 进阶优化手段

6.1 Web Worker应用

// 主线程
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.onmessage = e => handleResult(e.data);

// worker.js
self.onmessage = function(e) {
  const result = heavyComputation(e.data);
  self.postMessage(result);
};
  • 将耗时计算移出主线程
  • 保持UI响应流畅
  • 合理使用OffscreenCanvas

6.2 WASM加速

// 加载WASM模块
WebAssembly.instantiateStreaming(fetch('module.wasm'))
  .then(obj => {
    // 调用WASM函数
    obj.instance.exports.compute();
  });
  • 性能敏感场景使用WASM
  • 图像/视频处理加速