# 前端性能优化实战指南
## 核心优化策略
### 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(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';
}
}
function resizeAll() {
requestAnimationFrame(() => {
const widths = boxes.map(box => box.offsetWidth);
widths.forEach((w, i) => {
boxes[i].style.width = w + 10 + 'px';
});
});
}
.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. 缓存策略
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);
})
);
});
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
}
性能监控方案
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);
进阶优化技巧
- WebAssembly应用:将计算密集型任务移植到Wasm模块
- Web Worker使用:将长时间运行的任务移出主线程
- CSS Containment:限制浏览器重绘范围
.widget {
contain: layout paint style;
}
工具推荐