You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(stress_perf_rn): replace JS-dispatch timer with rAF-after-commit mount time (#137)
* perf(stress_perf_rn): replace JS-dispatch timer with rAF-after-commit mount time
Cross-team review of the StocksGrid perf numbers flagged that RN-Fabric's
in-app `Avg Update` and `Avg/Peak Memory` were measuring the wrong things
and were not comparable to the C# variants:
- `setSnapshot` returns immediately on Fabric while reconcile → Fabric →
Yoga → Composition continues across other threads, so a JS-side
begin/end stopwatch only captured dispatch. Confirmed empirically:
the new mount metric reports 348–1046 ms across 10–100% workloads,
vs. 0.5–6 ms from the old timer (170–700× undercount).
- `performance.memory.usedJSHeapSize` excludes Hermes, JSI, Fabric
shadow tree, Yoga, and text caches — tens-to-hundreds of MB of
RN-fixed cost. The harness already samples `WorkingSet64` externally
for every variant, so the in-app memory lines were redundant *and*
misleading.
Changes:
- PerfTracker.ts: drop `beginUpdate/endUpdate` + `Avg Update`. Add
`beginMount` (stamp T0 before setState) + `recordMountCommit` (called
from a useLayoutEffect on the dispatched state, schedules one rAF
and records `(rAF-now − T0)` as a sample). Drop `Avg/Peak Memory`
from the human-readable report; rename in-app heap reading to
`jsHeapMB` and the samples-CSV column to `JsHeap_MB` to disambiguate
it from process RSS.
- App.tsx: wire `beginMount` ahead of `setSnapshot` and add a
useLayoutEffect on `snapshot` that calls `recordMountCommit`.
Toolbar labels updated.
- VirtualList sibling: relabel in-app memory as `jsHeapMB` for
consistency (no `Avg Update` to remove there — it benchmarks scroll
P50/P95/P99 from rAF deltas, which doesn't have the async problem).
- run_stocks_grid_baseline.ps1 / run_full_matrix.ps1: parse `Avg Mount`
into a new `InAppAvgMountMs(_Med)` column. Median filters NaN so
C# rows (no Mount) and RN rows (no Update) don't pollute each
other's medians.
- METHODOLOGY.md: new sections explaining `Avg Update` (C#) vs
`Avg Mount` (RN) and JS heap vs `WorkingSet64`. Added Don'ts 2a/2b
to keep this from regressing.
- docs/reports/stress-perf-stocks-grid.md: stronger memory caveat
noting the RN engine baseline isn't decomposed; new open questions
for engine-baseline measurement and true JS-to-pixel mount via the
RNW Fabric perf wiki.
* perf(stress_perf_rn): queue mount-start timestamps; fix grammar nit
Address PR review feedback:
- PerfTracker.ts: replace single `lastMountStart` with a `pendingMountStarts`
queue. Multiple `beginMount()` calls before a commit (React batches state
updates under load) all queue; `recordMountCommit()` consumes the oldest
(worst-case user-perceived latency, not the optimistic latest), clears
the rest (a batched commit reflects all queued dispatches), and an empty
queue means no sample (avoids attributing stale stamps to unrelated
later commits — e.g. a re-render not driven by a `setSnapshot` tick).
- METHODOLOGY.md: "Under at light load" → "Under-reports at light load"
(parallel structure with "bursty at saturation").
0 commit comments