性能优化建议
组件开发规范和性能优化是前端工程化的重要组成部分。合理的规范和优化手段可以提升代码质量、可维护性和运行效率,降低维护成本。
组件开发规范
命名规范
组件命名采用大驼峰式(PascalCase),与文件名保持一致。例如:
// Button.jsx
function Button() {
return <button>Click</button>;
}
// IconButton.jsx
function IconButton() {
return <button>🔔</button>;
}
目录结构
推荐按功能划分组件目录:
components/
├── common/ # 通用组件
│ ├── Button/
│ │ ├── index.jsx
│ │ ├── style.module.css
│ │ └── test.js
├── features/ # 业务组件
│ ├── UserCard/
│ │ ├── index.jsx
│ │ └── hooks.js
Props 设计
- 使用 PropTypes 或 TypeScript 定义类型
- 保持 props 扁平化,避免深层嵌套
- 为常用 props 设置合理默认值
interface CardProps {
title: string;
size?: 'sm' | 'md' | 'lg';
onClick?: () => void;
}
function Card({ title, size = 'md', onClick }: CardProps) {
// ...
}
状态管理
- 组件内部状态优先使用 useState
- 复杂状态逻辑提取为自定义 Hook
- 避免在组件中直接使用全局状态
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue(v => !v), []);
return [value, toggle];
}
function Switch() {
const [on, toggle] = useToggle();
return <button onClick={toggle}>{on ? 'ON' : 'OFF'}</button>;
}
性能优化建议
渲染优化
- 使用 React.memo 避免不必要的重渲染
- 合理使用 useMemo/useCallback 缓存计算结果
- 列表项必须添加 key 属性
const ExpensiveComponent = React.memo(function({ data }) {
// 只在 data 变化时重渲染
return <div>{expensiveCalculation(data)}</div>;
});
function List({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
资源加载
- 代码分割按需加载
- 图片懒加载
- 预加载关键资源
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<LazyComponent />
</Suspense>
);
}
内存管理
- 及时清理事件监听器
- 避免内存泄漏
- 大型数据集使用虚拟列表
function ScrollListener() {
useEffect(() => {
const handleScroll = () => {
console.log(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
}
CSS 优化
- 避免深层嵌套选择器
- 使用 CSS Modules 或 styled-components
- 减少重排重绘操作
/* 避免 */
.container .list .item .icon {
color: red;
}
/* 推荐 */
.itemIcon {
color: red;
}
构建优化
- 使用 Tree Shaking 移除未引用代码
- 代码压缩混淆
- 合理配置 splitChunks
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
},
},
},
},
};
性能监控与分析
性能指标测量
- 使用 Performance API 获取关键指标
- 监控首次内容绘制(FCP)
- 跟踪最大内容绘制(LCP)
// 测量函数执行时间
function measure() {
performance.mark('start');
// 执行代码
performance.mark('end');
performance.measure('measure', 'start', 'end');
const duration = performance.getEntriesByName('measure')[0].duration;
console.log(`执行耗时: ${duration}ms`);
}
Chrome DevTools 使用技巧
- Performance 面板记录运行时性能
- Memory 面板分析内存使用
- Coverage 面板查看代码利用率
// 手动触发垃圾回收(仅用于调试)
if (window.gc) {
window.gc();
}
真实用户监控(RUM)
- 收集 FP/FCP/LCP 等指标
- 跟踪 JavaScript 错误
- 监控 API 请求性能
// 上报性能数据
function reportPerf() {
const timing = window.performance.timing;
const loadTime = timing.loadEventEnd - timing.navigationStart;
navigator.sendBeacon('/analytics', { loadTime });
}
window.addEventListener('load', reportPerf);
常见性能问题解决方案
长列表渲染
- 使用虚拟滚动技术
- 实现分页加载
- 减少 DOM 节点数量
import { FixedSizeList as List } from 'react-window';
function BigList({ items }) {
return (
<List
height={500}
itemCount={items.length}
itemSize={50}
width="100%"
>
{({ index, style }) => (
<div style={style}>{items[index]}</div>
)}
</List>
);
}
动画性能
- 使用 transform/opacity 属性
- 启用 GPU 加速
- 避免在动画中使用 JavaScript
/* 高性能动画 */
.box {
transition: transform 0.3s ease;
will-change: transform;
}
.box:hover {
transform: scale(1.1);
}
高频事件处理
- 使用防抖/节流
- 使用 passive 事件监听
- 避免在事件处理中执行重操作
// 节流实现
function throttle(fn, delay) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
fn.apply(this, args);
}
};
}
window.addEventListener('scroll', throttle(handleScroll, 100));
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:可访问性要求