Skip to main content

react-devtools-profile

Use when analyzing a React DevTools Profiler export (.json with "dataForRoots"/"commitData") — re-render storms, commit fan-out, "why did this component render", send/interaction render cost. NOT for Chrome Performance traces (those have "traceEvents" — use electron-profile).

소스 정보

저장소
keybase/client
최근 소스 활동
2026년 7월 13일 17:02
감지된 SKILL.md 언어
영어
스타
9,269
포크
1,287

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
4 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
react-devtools-profile
description
Use when analyzing a React DevTools Profiler export (.json with "dataForRoots"/"commitData") — re-render storms, commit fan-out, "why did this component render", send/interaction render cost. NOT for Chrome Performance traces (those have "traceEvents" — use electron-profile).
# React DevTools Profiler Export Analysis Parse React DevTools Profiler exports (version 4/5 JSON, top-level `dataForRoots`) with Python scripts in `scripts/` — no DevTools UI needed. Works for React Native and web/Electron profiles alike. Distinguish from a Chrome Performance trace: profiler export has `{"version": N, "dataForRoots": [...]}`; a trace has `traceEvents` (use the electron-profile skill for those). ## Workflow 1. **Overview** — commit totals, top commits with updaters, component ranking by aggregate self duration, timeline buckets: ```bash python3 scripts/profile-overview.py <profile.json> [--top 25] [--bucket-ms 500] ``` 2. **Per-commit detail** — full updater list, fiber counts, top fibers with ancestor paths, changeDescriptions if recorded: ```bash python3 scripts/profile-commits.py <profile.json> [--commit N] [--top 10] [--root 0] ``` Run from the skill directory (or use absolute script paths); both scripts need `scripts/rdtlib.py` alongside. The overview's top-commit list prints `#N` — that is the index to pass as `--commit N` (commits are chronological). ## Interpreting results | Signal | Meaning | |---|---| | `updaters` on a commit | Fibers that *scheduled* the update — setState / store subscription (useSyncExternalStore) firing. The render entry point, not necessarily where time went. | | Same broad updater set repeated across several commits | Shared-store fan-out: many components' selectors woke for one logical change. Find the common denominator subscription (here it was conversation meta) and fix identity churn there. | | Unnamed fibers `#1234` | Fiber absent from the end-of-profiling snapshot = unmounted before profiling stopped (virtualized-list churn, pending rows replaced on server ack). Cross-reference the same id in `updaters`, which carries displayName. | | `prio=Immediate` | Sync flush — store setState outside a React event (zustand, RPC callbacks). Each one blocks the frame; many small Immediate commits = stacked sync flushes worth batching. | | High `x<count>` in component ranking | Component rendered in many commits — subscription too broad or unstable selector output (fresh object/closure identity per run defeats useShallow). | | Large single-fiber self time in a big-fiber-count commit | Usually a subtree mount (new list row). Mount cost is mostly inherent; look at whether it mounts twice (key churn). | | `changeDescriptions: null` | Profile recorded without "Record why each component rendered". Re-record with it enabled to get props/state/hooks/context attribution per fiber. | **Scope caveat:** durations are React render/effect time only. Store selector runs, native layout, bridge, and app JS outside render are invisible here — a small total does NOT mean no perf problem; it means the problem isn't React commits. **Fan-out diagnosis recipe:** overview → spot repeated updater sets → per-commit to list exact updater components → read their store selectors → find the shared subscription whose selected values change identity without changing content → preserve identity at the producer (deep-equal reuse on store write), not with deeper memo at consumers. ## Gotchas - Timestamps are ms relative to profiling start; scripts print t= relative to first commit. - `fiberActualDurations` = inclusive per fiber; `fiberSelfDurations` = self. Ranking uses self. - Multiple roots possible (`dataForRoots`); overview iterates all, per-commit takes `--root`. - Updater lists carry displayNames even for fibers missing from the snapshot — best way to name unmounted fibers.
GitHub에서 보기