Token导航 LogoToken导航

Agent Skill · 开发

react-render-performance(React render 性能)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

react-render-performance 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为只读;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 14,701。

总安装 672周安装 28GitHub Stars 2下载 224核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:react-render-performance(React render 性能)
来源仓库:https://github.com/jonmumm/skills
仓库路径:skills/react-render-performance
安装命令:
npx skills add https://github.com/jonmumm/skills --skill react-render-performance
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/jonmumm/skills --skill react-render-performance

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

专注 React 组件渲染速度提升,通过算法优化与 DOM 操作精简达成流畅体验。适用于列表滚动卡顿、动画掉帧或大数据量展示时的响应迟缓问题。可建议虚拟滚动、分片渲染及 requestIdleCallback 等延迟处理技术。需区分 CPU 密集型与 IO 密集型任务,采取差异化的优化策略组合。

在低端设备上重点测试极端情况下的表现,确保普惠用户体验达标。

来源仓库内路径:skills/react-render-performance

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/jonmumm/skills --skill react-render-performanc…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它标注为只读,先用只读任务试一次,确认行为符合预期再扩大使用范围。

常见问题

6 条

react-render-performance 怎么安装?

在终端执行 npx skills add https://github.com/jonmumm/skills --skill react-render-performance。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

react-render-performance 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

react-render-performance 需要什么权限?

权限级别是只读。该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

react-render-performance 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

react-render-performance 用的人多吗?

公开数据是累计安装 672 次,近一周安装 28 次,下载 224 次,GitHub 2 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

react-render-performance 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。
  • 标注为只读权限,试用阶段不容易误改本地文件。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。
  • 只想先试试效果、不希望它改动本地文件的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
react-render-performance

React render 性能 · 本页

6722只读未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

React Render Performance

Patterns for minimizing unnecessary React re-renders when consuming external state. Prefer selector-based subscriptions over useState(wholeObject) — subscribe only to the slice each component needs.

Core idea

Storing a full state object in React state (e.g. useState(snapshot) and subscribing to every change) forces re-renders on any update. A component that only needs phase will still re-render when quiz.selectedWrong changes if both live in the same object.

Avoid: subscribe → setState(fullObject) → read a field in render. Prefer: subscribe to a selector or slice so the component re-renders only when that value changes. Every library below supports this; use it.

Tree position matters. The higher a component is in the tree, the more expensive a re-render becomes, because React re-renders it and all descendants. Subscribing to the whole store in App.tsx is especially bad — every store change re-renders the entire app. Push subscriptions down to the leaf or route-level components that actually need the data, or use selectors so high-level components only re-render when their slice changes.


Library patterns

XState (actors) — @xstate/react

Use useSelector(actor, selector) so the component re-renders only when the selected value changes.

// GOOD: stable selector — re-renders only when phase changes
import { useSelector } from "@xstate/react";
import { selectPhase } from "./selectors";

function PhaseIndicator({ actor }) {
  const phase = useSelector(actor, selectPhase);
  return <Text>{phase}</Text>;
}
// BAD: full snapshot in React state — re-renders on every actor change
const [snapshot, setSnapshot] = useState(null);
useEffect(() => {
  const sub = actor.subscribe((snap) => setSnapshot(snap));
  return () => sub.unsubscribe();
}, [actor]);
const phase = snapshot?.value?.sessionFlow; // unnecessary re-renders

Actor + ref for callbacks: Keep the actor in useState (so useSelector re-subscribes if the actor is replaced) and in a useRef for synchronous access in event handlers:

const [actor, setActor] = useState(() => {
  const a = createActor(machine);
  a.start();
  return a;
});
const actorRef = useRef(actor);
actorRef.current = actor;

function send(event) {
  actorRef.current.send(event);
}

@xstate/store — @xstate/store-react

Use useSelector(store, selector) to subscribe to a slice of store context. Re-renders only when the selected value changes (strict equality by default; optional custom compare).

// GOOD: select one field — re-renders only when count changes
import { createStore, useSelector } from "@xstate/store-react";

const store = createStore({
  context: { count: 0, name: "" },
  on: { inc: (ctx) => ({ ...ctx, count: ctx.count + 1 }) },
});

function CountDisplay() {
  const count = useSelector(store, (state) => state.context.count);
  return <span>{count}</span>;
}
// BAD: selecting whole context — re-renders on any context change
const context = useSelector(store, (state) => state.context);
return <span>{context.count}</span>;

Custom comparison when the selector returns an object:

const user = useSelector(
  store,
  (state) => state.context.user,
  (prev, next) => prev.id === next.id
);

Zustand

Use the store with a selector as the first argument. The component re-renders only when the selected value changes (referential equality).

// GOOD: selector — re-renders only when count changes
const count = useStore((state) => state.count);

// GOOD: primitive or stable ref — minimal re-renders
const phase = useStore((state) => state.session.phase);
// BAD: no selector — re-renders on every store change
const state = useStore();
return <span>{state.count}</span>;
// BAD: selecting a new object every time — re-renders every time
const { count, name } = useStore((state) => ({ count: state.count, name: state.name }));
// Use two selectors or useShallow instead

Use a module-level selector so the function reference is stable (see Selector rules below). For multiple fields, use useShallow or pick primitives:

import { useShallow } from "zustand/react/shallow";
const { count, name } = useStore(useShallow((state) => ({ count: state.count, name: state.name })));

Redux — react-redux

Use useSelector(selector) and select the smallest slice needed. Redux uses referential equality; selecting a new object every time forces re-renders.

// GOOD: select a primitive or stable reference
const phase = useSelector((state) => state.session.phase);
const count = useSelector((state) => state.counter);
// BAD: selecting whole slice — new object ref when any part of session updates
const session = useSelector((state) => state.session);
return <span>{session.phase}</span>;

For object slices use shallowEqual or a memoized selector:

import { shallowEqual, useSelector } from "react-redux";

const { phase, step } = useSelector(
  (state) => ({ phase: state.session.phase, step: state.session.step }),
  shallowEqual
);

Nanostores — @nanostores/react

Nanostores doesn’t take a selector in the hook; shape your stores so each consumer subscribes to a small store. Use computed stores to derive slices, or split state into multiple atoms.

// GOOD: one atom per logical slice, or computed for a derived slice
import { atom, computed } from "nanostores";
import { useStore } from "@nanostores/react";

const $session = atom({ phase: "idle", step: 0 });
const $phase = computed($session, (s) => s.phase);

function PhaseIndicator() {
  const phase = useStore($phase); // re-renders only when phase changes
  return <Text>{phase}</Text>;
}
// BAD: one big store, useStore on the whole thing — re-renders on any change
const $app = atom({ session: {...}, quiz: {...}, ui: {...} });
function PhaseIndicator() {
  const app = useStore($app);
  return <Text>{app.session.phase}</Text>;
}

Use map or atoms for granular updates and computed for derived values; then each component useStores only the store it needs.


React context

Context re-renders all consumers when the value reference changes. Prefer splitting by update frequency or exposing a subscribable store and selecting in the consumer.

// GOOD: split by update frequency
<FrequentContext.Provider value={frequentData}>
  <RareContext.Provider value={rareData}>
    {children}
  </RareContext.Provider>
</RareContext.Provider>
// GOOD: store in context, select in consumer (e.g. Zustand store, XState actor)
function useSessionPhase() {
  const store = useContext(StoreContext);
  return useSelector(store, (s) => s.phase);
}
// BAD: one context with everything — any change re-renders all consumers
<AppContext.Provider value={{ user, session, theme, settings, ... }}>

useSyncExternalStore (custom stores)

For stores that aren’t one of the above, use React’s useSyncExternalStore and subscribe to a slice in getSnapshot so the component only re-renders when that slice changes.

// GOOD: getSnapshot returns only the slice this component needs
const phase = useSyncExternalStore(
  store.subscribe,
  () => store.getSnapshot().session.phase,
  () => store.getSnapshot().session.phase
);
// BAD: getSnapshot returns full state — re-renders on every store change
const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
return <span>{state.session.phase}</span>;

Selector rules

  1. Keep selectors at module level — not inline in the component. Inline arrow functions create new references each render and can defeat equality checks.
// GOOD
const selectPhase = (snap) => snap.value?.sessionFlow;
function MyComponent({ actor }) {
  const phase = useSelector(actor, selectPhase);
}

// BAD — new function ref every render
function MyComponent({ actor }) {
  const phase = useSelector(actor, (snap) => snap.value?.sessionFlow);
}
  1. Return primitives or stable references. If the selector returns a new object/array every time, the component will re-render on every update. Prefer primitives or use a custom comparison when you must return an object.
  2. Don’t put expensive derivation in selectors. Heavy work belongs in useMemo in the component, not in the selector (selectors run often).

Anti-patterns

Anti-patternWhy it's badFix
setState(fullSnapshot) in subscribeEvery store/actor change re-rendersUse selector / slice (useSelector, selector arg, computed store)
No selector / whole store in hookSame as abovePass selector to useStore/useSelector; or use computed/small stores
Inline selector functionNew reference each renderModule-level selector
Selector returns new object every timeAlways re-rendersReturn primitive or use shallowEqual/custom compare
Mega-context with everythingAny update re-renders all consumersSplit context or put a store in context and select in consumer

When to use selectors

Use a selector / slice when:

  • The component needs 1–2 fields from a larger state
  • Different fields update at different rates (e.g. phase rarely, quiz state often)
  • Several components each need different parts of the same store
  • The component is high in the tree (e.g. App.tsx, layout, root route) — re-renders there cascade down the whole tree, so avoid subscribing to the whole store at that level

A single subscription is OK when:

  • The component needs most or all of the state
  • Updates are rare (e.g. user profile)
  • There’s only one consumer or it’s a leaf with no children

Rule of thumb: If a component re-renders more often than its visible output changes, add a selector (or a computed/small store). Use React DevTools Profiler to confirm.

平台分布

Codex

34.65%
按下载量换算78

Claude

29.66%
按下载量换算66

Cursor

20.3%
按下载量换算45

Gemini CLI

9.48%
按下载量换算21

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills