关于 react-component-performance
面向 React 开发者的性能排查技能,可定位组件渲染瓶颈并在不改变界面行为的前提下优化。它结合状态隔离、定向记忆化和 React DevTools Profiler 验证。
主要功能
- 01定位渲染触发因素与热点
- 02隔离频繁变化的状态
- 03稳定属性和回调
- 04减少计算量与列表渲染规模
- 05对比性能分析记录
适用场景
- 01排查 React 交互迟缓
- 02避免计时器更新导致大列表重渲染
- 03优化属性稳定的列表行
- 04对照基线验证优化效果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dimillian/ skills --skill react-component-performance安装后在 Claude Code 中输入/react-component-performance确认已加载。
附带文件agents/openai.yamlreferences/examples.md
详细介绍
React 组件性能
概述
找出渲染热点,隔离开销较大的更新,并实施有针对性的优化,同时不改变 UI 行为。
工作流
- 复现或描述性能变慢的情况。
- 找出触发重新渲染的因素(状态更新、属性频繁变化、Effect)。
- 将频繁变化的状态与开销较大的子树隔离。
- 稳定属性和处理函数;在值得时进行记忆化。
- 减少开销较大的工作(计算、DOM 大小、列表长度)。
- 验证:打开 React DevTools Profiler → 录制交互 → 检查火焰图,找出渲染时间超过约 16 ms 的组件 → 与优化前的基线录制结果进行比较。
检查清单
- 测量:使用 React DevTools Profiler 或记录渲染日志;捕获基线。
- 找出频繁更新:识别由计时器、滚动、输入或动画触发的状态更新。
- 拆分:将不断变化的状态移入子组件;保持开销较大的列表静态。
- 记忆化:仅当属性稳定时,才用
memo包装叶节点行组件。 - 稳定属性:对处理函数和派生值使用
useCallback/useMemo。 - 避免在渲染时执行派生计算:预先计算,或在记忆化辅助函数中计算。
- 控制列表大小:对长列表使用窗口化/虚拟化;避免渲染隐藏项目。
- 键:确保键稳定;顺序可能变化时避免使用索引。
- Effect:检查依赖数组;避免每次渲染都重新运行的 Effect。
- 样式/布局:留意开销较大的布局抖动,或大型 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