Manual row memo ablation

This is a separate manual-app experiment, not the compiler/manual/baseline comparison. Both arms use the same source and dependencies; only the outer IncidentRow memo wrapper differs. ON retains it; OFF executes the same row implementation without it. Provider values, callbacks, derived calculations, child button memoization, DOM and workflows are unchanged.

Removing the row wrapper does not reproduce compiler caching inside the row. This experiment isolates that wrapper's contribution; it does not establish compiler equivalence.

Production responsiveness

Chromium 145.0.7632.6; React 19.3.0; viewport 1440 x 900; 4x CDP CPU throttle. Three fresh-context blocks, ten paired trials per block, one warm-up workflow per arm per block. ON-first/OFF-first order is balanced and seeded-shuffled (seed 20260929). Reset work occurs outside timing. All three actions run in the same order within each trial, and behavior snapshots match across arms.

Timers start in the target button's click listener before React's handler. DOM readiness stops when the intended DOM change is observed; the second animation-frame callback is only a presentation opportunity, not actual paint. Neither metric includes pre-dispatch input delay or measures INP. No React Profiler or fiber probe runs in the production timing pages.

Action Metric ON median (ms) OFF median (ms) Mean paired saving (ms) Block-mean 95% interval (ms)
switch queue DOM readiness 23.950 26.750 3.207 0.438 to 5.975
switch queue Two-frame opportunity 60.350 63.400 3.983 -3.141 to 11.107
select incident DOM readiness 4.850 8.300 3.237 3.136 to 3.337
select incident Two-frame opportunity 25.800 28.150 1.970 -0.837 to 4.777
favorite incident DOM readiness 5.400 8.350 2.820 2.152 to 3.488
favorite incident Two-frame opportunity 24.650 26.600 1.963 0.630 to 3.297

Positive paired savings mean OFF was slower, favoring memo ON. These are differences within matched trials, not subtraction of unpaired medians. The interval uses three block means and Student-t with 2 degrees of freedom; it does not treat 30 trials as independent. Only three blocks were collected in one browser/hardware session, so uncertainty is exploratory and rests on independence/normality assumptions. An interval spanning zero is inconclusive, not proof of no effect or equivalence. Intervals are unadjusted across the displayed endpoints; there is no automatic winner or speed gate.

Shipped bundle size

Normal-production entry JavaScript, static imports and attached CSS are counted once. Gzip is measured per emitted file. Profiling builds, metadata, source maps and dynamic imports are excluded. ON-minus-OFF is a whole-build/minification delta, not the isolated size of React.memo itself.

Asset ON raw / gzip (bytes) OFF raw / gzip (bytes) ON minus OFF raw / gzip (bytes)
js 243636 / 74795 243624 / 74794 +12 / +1
css 12717 / 3489 12717 / 3489 0 / 0
total 256353 / 78284 256341 / 78283 +12 / +1

Intervention check: native profiling builds

Three profiling repetitions run without CPU throttling, separately from production timings. Row/button counts are the existing pinned-version React fiber diagnostic, not equivalent-cost CPU work or DOM mutations. Actual and base root/list durations remain in comparison.json; baseDuration is an estimate, not an uncached replay or measured savings. Inclusive parent/child durations are not added.

Action Rows ON / OFF Open buttons ON / OFF Favorite buttons ON / OFF List ACTUAL ON / OFF (ms) List BASE ON / OFF (ms)
switch queue 0 / 67 0 / 0 0 / 0 0.500 / 3.400 4.600 / 4.300
select incident 1 / 67 0 / 0 0 / 0 0.300 / 1.700 4.200 / 2.800
favorite incident 1 / 67 0 / 0 1 / 1 0.400 / 1.400 4.100 / 2.800

Reproduction and limitations

yarn benchmark:row-memo builds and measures this isolated experiment without overwriting the three-variant report. yarn benchmark:all also refreshes the main comparison with matching ablation evidence; CI publishes both together. Open report.html directly in a browser or follow its link from the hosted comparison.

Source fingerprint: 6d6ecfa4f1536b3dad063278e18e70c00e87eefdab9d65bd82ae25956d0b462e. Each build's arm, mode, React version and source fingerprint are checked before measurement and again during reporting. Raw order, blocks, paired samples, matched states and profiling actual/base records are in measurements.json; computed summaries are in comparison.json.

This fixed dataset and workflow do not cover real-user devices, first-load interactions, retained-cache memory or all possible application states. Repeated favorite toggles accumulate identical activity history in both arms; pairing controls that history, but later pairs need not have the same cost as earlier ones. Run independent sessions and choose a practical performance budget before drawing stronger conclusions.