MutationObserver's getReceiverFor is slow when there are a lot of observers
Categories
(Core :: DOM: Core & HTML, defect, P3)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox158 | --- | fixed |
People
(Reporter: julienw, Assigned: jjaschke)
References
Details
Attachments
(6 files)
Context: I'm building a Lit-based app using mozilla-central MozLitElement. This is a wrapper on the upstream LitElement class that handles localization through Fluent by using Fluent's connectRoot on every shadow root: https://searchfox.org/firefox-main/rev/938e8f38c6765875e998d5c2965ad5864f5a5ee2/toolkit/content/widgets/lit-utils.mjs#160
This in turns calls observe on this root: https://github.com/projectfluent/fluent.js/blob/9a183312d4db035d6002c93e03f0c169a58f3234/fluent-dom/src/dom_localization.js#L149
Then I noticed that the MutationObserver machinery and especially getObserverFor take a big chunk of the time spent on some page that has a lot of these elements, see this profile:
https://share.firefox.dev/469NE0A
There aren't a lot of these elements, I can count 818 fluent roots on this page. I wonder if there could be some easy optimisation here.
I'm also not sure using fluent-dom is the best model with Lit, and may switch to another (custom?) solution later. Also there may be an issue in Fluent.
I tried to do a simple testcase with ~1000 elements but the problem doesn't appear. So I'll try to make a smaller version of my app.
| Reporter | ||
Comment 1•1 year ago
|
||
Not exactly a minimal testcase but this reproduces the problem.
The full project is at https://github.com/julienw/mutationobserver-issue in case you'd like to tweak it.
The html file is generated with npm run build and it's then dropped to dist.
Updated•1 year ago
|
Comment 2•1 year ago
|
||
I don't see anything obvious to optimize.
| Reporter | ||
Updated•1 year ago
|
| Reporter | ||
Comment 3•1 month ago
|
||
Here is a new profile with latest nightly: https://share.firefox.dev/4xOTM9L
It's significatively different now, but still too slow. But maybe the slowness is unavoidable given how MutationObserver works.
I guess one solution to reduce the issue would be to have several observers, not just 1 for all roots.
Another solution could be to have an observer that could pierce shadow roots.
Finally (a solution we'll likely implement for the Enterprise Console), a solution that doesn't use a MutationObserver at all, by hooking into Lit's lifecycle directly. The drawback is that we can't set data-l10n-ids directly, but it sounds like a reasonable constraint.
| Assignee | ||
Comment 4•1 month ago
|
||
Updated•1 month ago
|
| Assignee | ||
Comment 5•1 month ago
|
||
| Assignee | ||
Comment 6•1 month ago
|
||
| Assignee | ||
Comment 7•1 month ago
|
||
| Assignee | ||
Comment 8•1 month ago
|
||
| Assignee | ||
Comment 9•1 month ago
|
||
Here is a profile of my local build (started after loading the test case, then clicking the button once): https://share.firefox.dev/4hlR8md (~490ms jank)
This is the profile with the patches applied: https://share.firefox.dev/4yVndYf (~371ms jank)
~25% improvement? Not bad I guess. I couldn't see any sp3 improvements though.
Comment 10•1 month ago
|
||
Comment 11•1 month ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/359c2e74b20c
https://hg.mozilla.org/mozilla-central/rev/1c44ebe7bfb7
https://hg.mozilla.org/mozilla-central/rev/f4202d8c0767
https://hg.mozilla.org/mozilla-central/rev/b95716a5cae3
https://hg.mozilla.org/mozilla-central/rev/9e5f4a90767f
Updated•23 days ago
|
Description
•