refactor(forms): avoid unnecessary Set allocation in maybeRemoveStaleArrayFields#69338
Open
arturovt wants to merge 1 commit into
Open
refactor(forms): avoid unnecessary Set allocation in maybeRemoveStaleArrayFields#69338arturovt wants to merge 1 commit into
arturovt wants to merge 1 commit into
Conversation
…ArrayFields Three small, behavior-neutral cleanups to maybeRemoveStaleArrayFields: 1. Avoid allocating an empty Set when prevData.byTrackingKey is undefined. new Set(undefined) previously created an unused empty Set on every call for parents with no tracking keys. 2. Guard the per-element tracking-key check on `oldTracking` being defined, skipping the isObject/hasOwn check entirely when there's nothing to track. 3. Replace childValue.hasOwnProperty(identitySymbol) with Object.hasOwn(childValue, identitySymbol). hasOwnProperty throws on null-prototype array elements (Object.create(null)), which would crash computeChildrenMap. Object.hasOwn is null-prototype-safe and preserves "own property" semantics (does not match inherited identitySymbol values). 4. Replace `data.byTrackingKey?.delete(id)` with `data.byTrackingKey!.delete(id)`. The optional chaining was dead: if oldTracking.size > 0, prevData.byTrackingKey (and therefore data.byTrackingKey, same Map reference via the spread) is always defined. The `?.` masked this invariant; `!` documents it and would surface a runtime error instead of a silent no-op if the invariant is ever violated. Verified via performance.mark/measure instrumented directly inside the function (count=1 call for a single-field edit in both cases). Total duration dropped from ~0.7ms to ~0.1ms, consistent with the avoided Set allocation in (1) and (2).
9d4c2b0 to
a7fd658
Compare
JeanMeche
approved these changes
Jun 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three small, behavior-neutral cleanups to maybeRemoveStaleArrayFields:
Avoid allocating an empty Set when prevData.byTrackingKey is
undefined. new Set(undefined) previously created an unused empty
Set on every call for parents with no tracking keys.
Guard the per-element tracking-key check on
oldTrackingbeingdefined, skipping the isObject/hasOwn check entirely when there's
nothing to track.
Replace childValue.hasOwnProperty(identitySymbol) with
Object.hasOwn(childValue, identitySymbol). hasOwnProperty throws
on null-prototype array elements (Object.create(null)), which
would crash computeChildrenMap. Object.hasOwn is null-prototype-safe
and preserves "own property" semantics (does not match inherited
identitySymbol values).
Replace
data.byTrackingKey?.delete(id)withdata.byTrackingKey!.delete(id). The optional chaining was dead:if oldTracking.size > 0, prevData.byTrackingKey (and therefore
data.byTrackingKey, same Map reference via the spread) is always
defined. The
?.masked this invariant;!documents it andwould surface a runtime error instead of a silent no-op if the
invariant is ever violated.
Verified via performance.mark/measure instrumented directly inside
the function, tested on a mobile device. count=1 call for a single-
field edit in both cases; total duration dropped from ~0.7ms to
~0.1ms, consistent with the avoided Set allocation in (1) and (2).
This is a per-call cost: a single array-valued field triggers one
call. A form with ~100 such fields would see this cost ~100x per
edit. At the unoptimized ~0.7ms/call, that's ~70ms for 100 fields —
over 4 frames at 60Hz (16.6ms budget), tighter still on 90/120Hz
mobile displays (11.1ms/8.3ms). After this change (~0.1ms/call,
~10ms for 100 fields), the same edit fits within a single 60Hz
frame budget.