# 前端性能优化实战指南
## 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 减少重排重绘
const fragment = document.createDocumentFragment();
items.forEach(item => {
fragment.appendChild(createItemElement(item));
});
container.appendChild(fragment);
- 使用transform代替top/left动画
- 避免频繁读写DOM属性
- 使用will-change提示浏览器
2.2 虚拟列表优化
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');
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 数据缓存
import useSWR from 'swr';
function Profile() {
const { data, error } = useSWR('/api/user', fetcher);
}
- 接口数据合理缓存
- 避免重复请求相同数据
- 实现本地数据持久化
5. 监控与持续优化
5.1 性能指标监控
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getLCP(console.log);
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);
self.onmessage = function(e) {
const result = heavyComputation(e.data);
self.postMessage(result);
};
- 将耗时计算移出主线程
- 保持UI响应流畅
- 合理使用OffscreenCanvas
6.2 WASM加速
WebAssembly.instantiateStreaming(fetch('module.wasm'))
.then(obj => {
obj.instance.exports.compute();
});