fix: release settings form controls on unmount#42752
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
|
Builds ready [6e95b11]
⚡ Performance Benchmarks (Total: 🟢 13 pass · 🟡 11 warn · 🔴 0 fail)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
✨ Files requiring CODEOWNER review ✨👨🔧 @MetaMask/core-extension-ux (2 files, +69 -0)
|
ameliejyc
left a comment
There was a problem hiding this comment.
Manually tested and looks fine to me!



Description
The
settings-routememory profile still retained one detached Settings page per route cycle after the shared image-listener fix. Heap snapshots showed the full settings subtree retained through React 17's per-node non-delegated listener on the native select:V8EventListener -> native_bind -> select[data-testid="default-address-scope-dropdown"] -> parent settings DOM subtreeReact 17 attaches per-node non-delegated listeners to form controls such as
input,select, andtextarea. On Settings unmount, this change detaches those retained listener targets and clears React's private host references so a retained listener target cannot keep the entire Settings tree alive. The cleanup is scoped to Settings and covered by a unit test that verifies the retained select is detached and scrubbed on unmount.Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
source ~/.nvm/nvm.sh && nvm use && yarn build:testsource ~/.nvm/nvm.sh && nvm use && yarn llm:memory -- --iterations 20 --flow settings-route --sample final --probe cdp --snapshot both --output test-artifacts/memory/settings-route-detach-form-controls-probe-cdp-heap-20.jsonPR: test: add memory profiling CLI for extension flows #42733
Profiler evidence:
settings-routebefore this change, after the earlier Safe Chains and image-listener fixes: runtime+10.49 MiB, JS+6.89 MiB, DOM nodes+5581, JS listeners+534over 20 iterations.settings-routeafter this change: runtime+5.60 MiB, JS+3.49 MiB, DOM nodes+183, JS listeners+55over 20 iterations.default-address-scope-dropdown; remaining retainedmaskiconimage nodes are detached from the settings tree.Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Adds manual DOM cleanup during Settings unmount, which could inadvertently remove or interfere with elements if the selector scope or ref wiring is wrong. Changes are localized to the Settings page and covered by a new unit test.
Overview
Prevents Settings-route memory retention by adding an unmount cleanup in
SettingsLayoutthat findsinput/select/textarea/imgunder the settings root, deletes React 17 internal__reactFiber$/__reactProps$references, and removes those nodes from the DOM.Adds a regression test that mounts Settings with the default-address dropdown enabled, injects fake React internals onto the
<select>, unmounts, and asserts the element is detached and the internal keys are cleared.Reviewed by Cursor Bugbot for commit 6e95b11. Bugbot is set up for automated code reviews on this repo. Configure here.