NXT-10864 [Enact] Spottable - Investigate performance improvements#3402
NXT-10864 [Enact] Spottable - Investigate performance improvements#3402dan-ichim-lgp wants to merge 8 commits intodevelopfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #3402 +/- ##
===========================================
- Coverage 86.70% 83.99% -2.72%
===========================================
Files 136 154 +18
Lines 5696 7417 +1721
Branches 1463 1954 +491
===========================================
+ Hits 4939 6230 +1291
- Misses 599 934 +335
- Partials 158 253 +95 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Looks ok, but i can suggest some improvements: 1 Spottable.js: line 153: Dead delete rest.spotlightId : spotlightId is already destructured out of props into its own variable at the top of SpottableBase, so it's never in rest to begin with
functional:
Object 2 can be modified to:
Since props (the rest object) is already a fresh copy, it can just be mutated in-place before passing Please test and let me know your opinion about the suggestions |
f60ee6c to
792f7de
Compare
|
please add information about the changes made after my comments, in the PR description |
* NXT-10623: Replace Travis CI with GitHub Actions Co-Authored-By: Claude Opus 4.6 <[email protected]> * NXT-10623: Add explicit permissions to GitHub Actions workflows Co-Authored-By: Claude Opus 4.6 <[email protected]> * NXT-10623: Use lts/* and node versions in CI matrix Replace hardcoded Node.js 20 with a matrix strategy using lts/* and node, matching the original Travis CI configuration. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
* Added linear scaled Screen Type * Activated `linearScaling` for testing * Small fix * Changed default value for `linear scaling type`; Added constraints for linear scale factor * Fixed `getLinearSize()` and added unit test for `linearScaling.type = 'currentScreen'` * Added `CHANGELOG` * small fix * Fixed eslint warnings * Added sampler for ResolutionDecorator * Removed `eslint-disable` * Fixed `unit-test`
Checklist
Issue Resolved / Feature Added
Reduced per-instance render overhead in spotlight/Spottable, with particular impact in VirtualList scrolling where many spottable items mount and re-render frequently.
Resolution
Five independent optimizations:
Removed redundant mount render (Spottable.js) — componentDidMount called forceUpdate(), a leftover from the ReactDOM.findDOMNode() era. With WithRef + useImperativeHandle, the DOM node is available before useLayoutEffect fires on the first render, making the second render unnecessary. Saves one full render per Spottable mount.
Converted Spottable class wrapper to a function component (Spottable.js) — the inner Spottable class existed only to hold a handleForceUpdate instance method. It is now a plain function component that calls useReducer for a stable, allocation-free force-update trigger, removing a class instance and its field allocation per mount.
Removed dead delete rest.spotlightId (Spottable.js) — spotlightId is already destructured out of props in SpottableBase, so it is never present in rest. The delete was a no-op on every render.
Conditional Spotlight.getCurrent() (SpottableCore.js) — didUpdate previously called getCurrent() on every render to re-sync this.isFocused. The call is now skipped unless spotlightDisabled is true or a selection cancel may fire. this.isFocused stays accurate via handleFocus/handleBlur events in all other cases. unload() re-queries getCurrent() directly at unmount to keep onSpotlightDisappear reliable.
Reduced per-render allocations (useSpottable.js) — three sources of unnecessary allocations eliminated:
context.current is now mutated in-place instead of being replaced with a new object each render.
A shared EMPTY_ATTRIBUTES constant is used when spotlightId is not set, avoiding an empty-object allocation on every render.
The props rest object (a fresh copy already created by destructuring) is mutated in-place before being passed to hook.setPropsAndContext, avoiding a second spread-merge allocation that previously occurred on every render.
Additional Considerations
No API or behavioral changes. Render-count expectations in shouldComponentUpdate tests updated to reflect the removed mount-time forceUpdate().
Links
NXT-10864
Related: findDOMNode removal — commit 33c27d5 (WRQ-19325)
Comments