<div id="test">Test</div>
const __OBSERVER = Symbol('observer');
const div = document.getElementById('test');
function update1() {
if(!div[__OBSERVER]) {
div[__OBSERVER] = new MutationObserver(mutations => update1());
} else {
div[__OBSERVER].disconnect();
}
div.style.opacity = parseInt(div.style.opacity) ? 0 : 1;
div[__OBSERVER].observe(div, { attributeFilter: ['style'] });
}
function update2() {
if(!div[__OBSERVER]) {
div[__OBSERVER] = new MutationObserver(mutations => update2());
} else {
div[__OBSERVER].disconnect();
}
div.style.opacity = parseInt(div.style.opacity) ? 0 : 1;
div[__OBSERVER].observe(div, { attributeFilter: ['style'] });
div[__OBSERVER].observe(div, { characterData: true, subtree: true });
}
update1();
update2();
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
disconnect/reconnect with 1 observe | |
disconnect/reconnect with 2 observes |
Test name | Executions per second |
---|---|
disconnect/reconnect with 1 observe | 1190947.1 Ops/sec |
disconnect/reconnect with 2 observes | 973994.2 Ops/sec |
The benchmark is designed to evaluate the performance of two different approaches to handling DOM mutation in a web environment using the MutationObserver
API, specifically comparing the performance in terms of execution speed between using one observer and two observers.
Test Case 1: update1()
update1()
function, which uses a single MutationObserver
to watch for changes in the style
attribute of a div
element. Test Case 2: update2()
update2()
function, which sets up two MutationObserver
instances for the same div
. One observes changes to the style
attribute, and the second observes character data changes and the entire subtree of the div
.update1
)Pros:
Cons:
update2
)Pros:
Cons:
MutationObserver
performance differently. Testing on multiple platforms is key to ensure consistent user experience.Polling: Another way to detect changes is to periodically check the DOM for updates using a setInterval method or similar polling strategy. However, this can be less efficient and more resource-intensive as it continuously checks for changes rather than responding to them.
Event Listeners: For some DOM events, leveraging standard event listeners (like click
, change
, etc.) can be more effective for certain types of user interactions and might be simpler to implement.
Framework-Specific Solutions: Libraries or frameworks such as React or Vue may provide their own abstractions and optimizations for handling DOM manipulations, potentially offering different performance characteristics and conveniences compared to direct usage of the MutationObserver
.
In this benchmark, the performance of handling DOM updates with one versus two MutationObserver
instances is tested, revealing important insights about resource management, complexity, and responsiveness in web applications. Understanding the trade-offs allows developers to make informed choices when deciding how to implement mutation detection in their applications.