关于 react-component-performance
面向 React 开发者的性能优化技能,用于定位组件卡顿和减少不必要的重渲染。它结合针对性优化方法,并通过 React DevTools Profiler 与基线记录对比验证效果。
主要功能
- 01定位重渲染原因与热点
- 02隔离频繁变化的状态
- 03稳定属性和回调引用
- 04减少计算与列表渲染
- 05分析并比较优化前后表现
适用场景
- 01诊断缓慢的 React 组件
- 02减少列表中的重复渲染
- 03通过性能分析验证优化
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ shipshitdev/ skills --skill react-component-performance安装后在 Claude Code 中输入/react-component-performance确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
plugin.jsonREADME.mdagents/openai.yamlreferences/examples.md详细介绍
React 组件性能
识别渲染热点,隔离开销较大的更新,并有针对性地优化,同时不改变 UI 行为。
适用场景
- 用户要求分析或改善运行缓慢的 React 组件时。
- 需要减少 React UI 中的重复渲染、列表卡顿或开销较大的渲染工作时。
对于 API 延迟、数据库查询、缓存、后台任务或基础设施调优,请改用 performance-expert。
工作流
- 重现或描述卡顿现象。
- 找出触发重复渲染的原因(状态更新、属性频繁变化、副作用)。
- 将快速变化的状态与开销较大的子树隔离开。
- 稳定属性和处理函数;在确有收益时使用记忆化。
- 减少开销较大的工作(计算、DOM 大小、列表长度)。
- 验证:打开 React DevTools Profiler → 录制交互 → 在火焰图中检查渲染时间超过约 16 ms 的组件 → 与优化前的基线录制结果对比。
检查清单
- 测量:使用 React DevTools Profiler 或记录渲染日志;采集基线。
- 查找频繁更新:确定哪些状态会因计时器、滚动、输入或动画而更新。
- 拆分:将持续变化的状态移入子组件;让开销较大的列表保持静态。
- 记忆化:仅当属性稳定时,才用
memo包装叶节点行组件。 - 稳定属性:对处理函数和派生值使用
useCallback/useMemo。 - 避免在渲染期间进行派生计算:预先计算,或在已记忆化的辅助函数中计算。
- 控制列表大小:对长列表使用窗口化/虚拟化;避免渲染隐藏项。
- 键:确保键稳定;当顺序可能变化时,避免使用索引。
- 副作用:检查依赖数组;避免每次渲染都重新运行的副作用。
- 样式/布局:留意开销较大的布局抖动或大型 Markdown/差异内容渲染。
优化模式
隔离持续变化的状态
将计时器或动画计数器移入子组件,避免父级列表在每次计时更新时重新渲染。
// ❌ Before – entire parent (and list) re-renders every second
function Dashboard({ items }: { items: Item[] }) {
const [tick, setTick] = useState(0);
useEffect(() => {
const id = setInterval(() => setTick(t => t + 1), 1000);
return () => clearInterval(id);
}, []);
return (
<>
<Clock tick={tick} />
<ExpensiveList items={items} /> {/* re-renders every second */}
</>
);
}
// ✅ After – only <Clock> re-renders; list is untouched
function Clock() {
const [tick, setTick] = useState(0);
useEffect(() => {
const id = setInterval(() => setTick(t => t + 1), 1000);
return () => clearInterval(id);
}, []);
return <span>{tick}s</span>;
}
function Dashboard({ items }: { items: Item[] }) {
return (
<>
<Clock />
<ExpensiveList items={items} />
</>
);
}
使用 useCallback + memo 稳定回调
// ❌ Before – new handler reference on every render busts Row memo
function List({ items }: { items: Item[] }) {
const handleClick = (id: string) => console.log(id); // new ref each render
return items.map(item => <Row key={item.id} item={item} onClick={handleClick} />);
}
// ✅ After – stable handler; Row only re-renders when its own item changes
const Row = memo(({ item, onClick }: RowProps) => (
<li onClick={() => onClick(item.id)}>{item.name}</li>
));
function List({ items }: { items: Item[] }) {
const handleClick = useCallback((id: string) => console.log(id), []);
return items.map(item => <Row key={item.id} item={item} onClick={handleClick} />);
}
优先在渲染之外派生数据
// ❌ Before – recomputes on every render
function Summary({ orders }: { orders: Order[] }) {
const total = orders.reduce((sum, o) => sum + o.amount, 0); // runs every render
return <p>Total: {total}</p>;
}
// ✅ After – recomputes only when orders changes
function Summary({ orders }: { orders: Order[] }) {
const total = useMemo(() => orders.reduce((sum, o) => sum + o.amount, 0), [orders]);
return <p>Total: {total}</p>;
}
其他模式
- 拆分行组件:将列表行提取为属性范围精简的记忆化组件。
- 延迟开销较大的渲染:对开销较大的内容采用延迟渲染,或在展开前将其折叠。
性能分析验证步骤
- 打开 React DevTools → Profiler 标签页。
- 点击 Record,执行导致卡顿的交互,然后点击 Stop。
- 切换到 Flamegraph 视图;标注了组件且耗时超过约 16 ms 的条形是候选对象。
- 使用 Ranked chart 按自身渲染时间排序,并针对排名靠前的问题项进行优化。
- 每次只应用一项优化,重新录制,并将渲染次数和耗时与基线对比。
示例参考
如果用户需要具体的重构示例,请加载 references/examples.md。
评论
支持 Markdown