Profiling tooling for the SDK row-render perf initiative.
Two options.
node perf/capture-hermes-profile.jsConnects to Metro's Hermes target, starts profiling, waits for Enter, writes a .cpuprofile into perf/profiles/, then auto-runs the analyzer.
- Run SampleApp on a device. Make sure Metro is up.
- Chromium →
chrome://inspect→ click inspect on the Hermes target. - DevTools → Performance tab → Record (Cmd+E).
- Do your scenario (open a channel with 30+ messages; scroll to trigger renders).
- Stop.
- Right-click the recording → Save profile… → save into
perf/profiles/(gitignored).
A 10–15 second profile is plenty for analysis.
node perf/analyze-cpuprofile.js perf/profiles/baseline.cpuprofileOutputs:
- Profile summary (duration, sample count, sample rate).
- ⚠ warning if the profile looks un-desymbolicated.
- Time by category — auto-bucketed by source:
Idle,GC,npm: <package>,SDK source,App source,builtin:Object,builtin:JSON,VM / native. No hand-curated patterns. - Time by source file.
- Top functions by self time (where the JS thread actually sits).
- Top functions by total time (which call sites dominate).
Optional drilldown into specific functions:
node perf/analyze-cpuprofile.js perf/profiles/x.cpuprofile \
--inside MessageWithContext,useCreateMessageContext,renderTextDev profiles collapse every frame into one Metro bundle URL, so categorization shows everything as App source. To recover per-package attribution, fetch Metro's source map and run the desymbolicator:
curl -s 'http://localhost:8081/index.map?platform=ios&dev=true&minify=false' \
-o /tmp/dev.map.json
node perf/desymbolicate-cpuprofile.js perf/profiles/x.cpuprofile /tmp/dev.map.json
node perf/analyze-cpuprofile.js perf/profiles/x.desymbolicated.cpuprofilenode perf/analyze-cpuprofile.js --diff perf/profiles/before.cpuprofile perf/profiles/after.cpuprofilePer-category self-time delta + top function self-time deltas (sorted by |delta|). Optional --grep <pattern> to zoom in on specific function names. Warns if sample rates between the two profiles diverge >10%.
For a fair diff, capture both profiles using the same scenario and the same device in roughly the same conditions.
For perf work where the bottleneck is memory pressure, MediaCodec slot usage, or frame timing — not JS-thread CPU — use the adb-based heap dump script.
perf/android-heap-dump.sh branch
perf/android-heap-dump.sh develop # after switching branches + rebuildThe script captures dumpsys meminfo, gfxinfo, media.codec, and procstats for the SampleApp and writes the combined output to perf/profiles/android-heap-<label>-<timestamp>.txt. Pre-test recipe (warming the video pool, resetting frame counters) is documented in the script header.
For A/B comparisons, run the same scenario on both branches and diff the Native Heap, Dalvik Heap, TOTAL PSS, MediaCodec instance count, and frame-time percentiles between the two output files.
- Keep captured
.cpuprofilefiles inperf/profiles/(gitignored). - Name files descriptively:
baseline.cpuprofile,step-8.cpuprofile, etc. - Profiles must be captured in dev mode (Metro) so function names are intact. Release builds are minified — desymbolicate with the matching source map if you need to analyze one.