mcpField
R
react-component-performance

react-component-performance

github.com/shipshitdev开发3988 次安装1 天前更新
代码仓库

关于 react-component-performance

面向 React 开发者的性能优化技能,用于定位组件卡顿和减少不必要的重渲染。它结合针对性优化方法,并通过 React DevTools Profiler 与基线记录对比验证效果。

主要功能

  1. 01定位重渲染原因与热点
  2. 02隔离频繁变化的状态
  3. 03稳定属性和回调引用
  4. 04减少计算与列表渲染
  5. 05分析并比较优化前后表现

适用场景

  1. 01诊断缓慢的 React 组件
  2. 02减少列表中的重复渲染
  3. 03通过性能分析验证优化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/shipshitdev/skills --skill react-component-performance

安装后在 Claude Code 中输入/react-component-performance确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

plugin.json
README.md
agents/
openai.yaml
references/
examples.md

详细介绍

React 组件性能

识别渲染热点,隔离开销较大的更新,并有针对性地优化,同时不改变 UI 行为。

适用场景

  • 用户要求分析或改善运行缓慢的 React 组件时。
  • 需要减少 React UI 中的重复渲染、列表卡顿或开销较大的渲染工作时。

对于 API 延迟、数据库查询、缓存、后台任务或基础设施调优,请改用 performance-expert。

工作流

  1. 重现或描述卡顿现象。
  2. 找出触发重复渲染的原因(状态更新、属性频繁变化、副作用)。
  3. 将快速变化的状态与开销较大的子树隔离开。
  4. 稳定属性和处理函数;在确有收益时使用记忆化。
  5. 减少开销较大的工作(计算、DOM 大小、列表长度)。
  6. 验证:打开 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>;
}
其他模式
  • 拆分行组件:将列表行提取为属性范围精简的记忆化组件。
  • 延迟开销较大的渲染:对开销较大的内容采用延迟渲染,或在展开前将其折叠。

性能分析验证步骤

  1. 打开 React DevTools → Profiler 标签页。
  2. 点击 Record,执行导致卡顿的交互,然后点击 Stop。
  3. 切换到 Flamegraph 视图;标注了组件且耗时超过约 16 ms 的条形是候选对象。
  4. 使用 Ranked chart 按自身渲染时间排序,并针对排名靠前的问题项进行优化。
  5. 每次只应用一项优化,重新录制,并将渲染次数和耗时与基线对比。

示例参考

如果用户需要具体的重构示例,请加载 references/examples.md。

评论

支持 Markdown