如何提高前端应用的性能
1. 代码优化
1.1 减少DOM操作
DOM操作非常消耗性能,应尽量减少:
// 不好的做法
for(let i=0; i<100; i++) {
document.getElementById('list').innerHTML += `<li>Item ${i}</li>`;
}
// 好的做法
let html = '';
for(let i=0; i<100; i++) {
html += `<li>Item ${i}</li>`;
}
document.getElementById('list').innerHTML = html;
1.2 使用事件委托
减少事件监听器数量:
// 不好的做法
document.querySelectorAll('li').forEach(li => {
li.addEventListener('click', handleClick);
});
// 好的做法
document.getElementById('list').addEventListener('click', (e) => {
if(e.target.tagName === 'LI') {
handleClick(e);
}
});
1.3 避免强制同步布局
读取样式前不要修改样式:
// 不好的做法
element.style.width = '100px';
const width = element.offsetWidth; // 强制同步布局
// 好的做法
const width = element.offsetWidth;
element.style.width = '100px';
2. 资源优化
2.1 图片优化
- 使用WebP格式
- 实现懒加载
- 使用srcset响应式图片
<img src="image.jpg"
srcset="image-480w.jpg 480w,
image-800w.jpg 800w"
sizes="(max-width: 600px) 480px,
800px">
2.2 代码分割
使用动态导入实现按需加载:
// 静态导入
import { heavyModule } from './heavyModule';
// 动态导入
button.addEventListener('click', async () => {
const { heavyModule } = await import('./heavyModule');
heavyModule.doSomething();
});
2.3 使用CDN加速
将静态资源部署到CDN:
<script src="https://cdn.example.com/react@18.2.0/umd/react.production.min.js"></script>
3. 缓存策略
3.1 合理配置HTTP缓存
# 静态资源长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
3.2 使用Service Worker
实现离线缓存:
// service-worker.js
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then((cache) => {
return cache.addAll([
'/',
'/index.html',
'/styles/main.css',
'/scripts/main.js'
]);
})
);
});
4. 渲染优化
4.1 减少重绘和回流
- 使用transform和opacity实现动画
- 使用will-change提示浏览器
.animate {
will-change: transform;
transition: transform 0.3s;
}
4.2 虚拟列表
大数据量列表渲染优化:
// 使用react-window
import { FixedSizeList as List } from 'react-window';
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
const Example = () => (
<List
height={500}
itemCount={1000}
itemSize={35}
width={300}
>
{Row}
</List>
);
5. 网络优化
5.1 预加载关键资源
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="critical.js" as="script">
5.2 使用HTTP/2
server {
listen 443 ssl http2;
# 其他配置...
}
5.3 压缩资源
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
6. 监控与持续优化
6.1 性能监控
使用Lighthouse和Web Vitals:
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getLCP(console.log);
6.2 性能预算
在package.json中设置性能预算:
{
"performance": {
"budgets": [
{
"resourceType": "script",
"budget": 100
},
{
"resourceType": "image",
"budget": 300
}
]
}
}
7. 框架最佳实践
7.1 React优化
- 使用React.memo
- 避免内联函数
- 合理使用useMemo/useCallback
const MemoizedComponent = React.memo(function MyComponent({ data }) {
/* 渲染逻辑 */
});
function Parent() {
const handleClick = useCallback(() => {
// 处理点击
}, []);
return <MemoizedComponent onClick={handleClick} />;
}
7.2 Vue优化
- 使用v-once
- 合理使用computed
- 避免v-if和v-for一起使用
<template>
<div v-once>{{ staticContent }}</div>
<div v-for="item in filteredItems" :key="item.id">{{ item.text }}</div>
</template>
<script>
export default {
computed: {
filteredItems() {
return this.items.filter(item => item.active);
}
}
}
</script>
总结
前端性能优化是一个系统工程,需要从代码编写、资源加载、渲染流程、网络传输等多个维度综合考虑。关键点包括:
- 减少不必要的DOM操作和重绘
- 优化资源加载策略
- 合理利用缓存
- 监控性能指标并持续优化
- 遵循框架最佳实践
实际项目中应根据具体场景选择最适合的优化手段,并通过性能测试验证优化效果。