Skip to content

Implement MutationObserver in the DOM polyfill - #624

Merged
andrewiggins merged 2 commits into
Shopify:mainfrom
airhorns:polyfill-mutation-observer
Sep 3, 2026
Merged

andrewiggins merged 2 commits into
Shopify:mainfrom
airhorns:polyfill-mutation-observer

Conversation

@airhorns

@airhorns airhorns commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

What changed

@remote-dom/polyfill currently installs and documents a MutationObserver constructor, but the constructor is an empty stub: new MutationObserver(callback).observe(node) throws because observe is undefined. This is especially easy to miss when remote code is type-checked against lib.dom.

This implements the observer surface over the polyfilled tree:

  • asynchronous, batched child-list, attribute, and character-data records
  • subtree, attributeFilter, and old-value options
  • observe(), disconnect(), and takeRecords()
  • standard callback and observation-option validation

Mutation delivery is integrated alongside the existing remote synchronization hooks, so observation does not change what is sent to a Remote DOM host.

Inactive-path performance

Mutation types maintain separate active-registration flags. Mutation sites check the corresponding flag before capturing old values or allocating a record, Map, or NodeList, and before walking ancestors. The registration WeakMap is created lazily and released again when the final observer disconnects. A child-list or character-data observer therefore does not add bookkeeping to attribute writes.

In a local Node 20.20 benchmark of one million repeated setAttribute() calls with no active observers (seven measured runs after warm-up), the median changed from 66.9ms to 47.0ms compared with the initial implementation in this PR, about 30% faster.

Validation

  • pnpm exec vitest run (180 tests)
  • pnpm lint
  • pnpm type-check
  • mise exec node@20.20.0 -- pnpm --filter @remote-dom/polyfill build

Assisted-By: devx/ca2f43ab-bbf9-4273-b1bc-0b06f8c90a57
Assisted-By: devx/ca2f43ab-bbf9-4273-b1bc-0b06f8c90a57
@airhorns
airhorns force-pushed the polyfill-mutation-observer branch from fb49553 to 7faf138 Compare September 1, 2026 17:50
@andrewiggins

Copy link
Copy Markdown
Contributor

Now that #652 has landed, I'd like to implement this as a built-in Window extension consumers can opt into

@andrewiggins andrewiggins left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gonna go ahead and merge this and then build on top of it

@andrewiggins
andrewiggins merged commit e2a9eef into Shopify:main Sep 3, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants