[audit] motion-dom/stats: dedupe summarise calls, inline helpers#3742
[audit] motion-dom/stats: dedupe summarise calls, inline helpers#3742mattgperry wants to merge 1 commit into
Conversation
Replace 15 explicit summarise() calls in reportStats with a small generic summariseAll helper that maps each sub-object's keys; inline the single-use mean() and msToFps() helpers; drop the defensive cancelFrame inside record() (reportStats already cancels before clearing the buffer). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Greptile SummaryThis PR refactors the debug-mode stats collection module (
Confidence Score: 5/5Safe to merge — purely mechanical refactoring with no behavioral changes and full test coverage. Every changed behavior was verified: the FPS min/max swap is mathematically identical to the old destructuring swap, No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "[audit] motion-dom/stats: dedupe summari..." | Re-trigger Greptile |
Directory
packages/motion-dom/src/stats/— debug-mode runtime stats collection.Exports
recordStats(called fromframer-motion/src/debug.tsandprojection.ts) plus the internalstatsBufferandactiveAnimationsthat hot-path code (JSAnimation, WAAPI start, projection node)
increments/decrements and conditionally reads from.
recordStatsis theonly public entry: it allocates buffer arrays, schedules
record()onevery
postRenderframe, and returns areportStats()closure thatsummarises the buffer into a
StatsSummary.Both lenses applied.
Performance
No changes. The per-frame work inside
record()is gated onstatsBuffer.value, so it's only active during an explicitrecordStats()profiling session. All hot-path call sites elsewherealready short-circuit on
if (statsBuffer.value)/if (statsBuffer.addProjectionMetrics)before touching the buffer, so there is no idle-cost to trim. The
reportStats()work (Math.min(...values)/Math.max(...values)/reduce) runs once when the user ends a session — not a hot path.Filesize
Measured per-file gzipped deltas after
yarn build:motion-dom/dist/motion-dom.jsmotion-dom/dist/motion-dom.dev.jsmotion-dom/dist/cjs/index.jsmotion-dom/dist/es/stats/index.mjsframer-motion/dist/framer-motion.jsframer-motion/dist/dom.jsframer-motion/dist/dom-mini.jsmotion-dom/dist/es/index.mjsUser-facing bundles drop ~110–126 gzipped bytes each.
Changes (all in
reportStats/summarise):summarise(value.X.Y)into a genericsummariseAllhelper that iterates each sub-object's keys. The summary object
shrinks from three nested literals (~700 chars pre-min) to three
helper calls. This is the bulk of the win.
mean()— thecalcAveragedefaultparameter was never overridden by any caller. Replaced with an
inline
reduceinsidesummarise.msToFps()— three call sites becomeMath.round(1000 / x)directly; the explicit array-destructuringswap becomes a single temp, which compresses slightly better.
cancelFrame(record)insiderecord()—reportStats()already callscancelFrame(record)before clearingthe buffer, so the null branch was unreachable. Replaced with a
simple
if (!value) return.No public API changed;
recordStats/statsBuffer/activeAnimationssignatures are identical.
Verification
yarn buildclean.yarn test— all stats tests pass (3/3 inmotion-dom/src/stats/__tests__/index.test.ts).One unrelated AnimatePresence test was flaky on the first run and
passed on re-run.
🤖 Generated with Claude Code