I know that MutationObservers callbacks may get called sometime after the DOM change. But the question is: What is the timing of these callbacks? Do the callbacks enter the event queue of the browsers? If so, when do they enter the queue?
Are the callbacks:
For example, if the following piece of code is executed (with setZeroTimeout defined here):
var target = document.body;
new MutationObserver(function(mutations) {
console.log('MutationObserver');
}).observe(target, {
attributes: true,
childList: true,
characterData: true
});
// Post message
setZeroTimeout(function () { console.log('message event'); });
// DOM mutation
target.setAttribute("data-test", "value");
Should "MutationObserver" be printed before "message event" or after it? Or is it implementation-defined?
I'm getting "MutationObserver" before "message event" on Chromium 26, though the DOM mutation is after message posting. Maybe this is indicating that MutationObserver callbacks are not using the event queue.
I have googled for HTML specification, DOM specification or browser implementation documents, but I didn't found anything related to this behavior.
Any explanation or documentation on the timing of MutationObservers callbacks please?
Good answer! Yes, it's finally slower by just 10% or even less in recent versions of Chrome. @Bergi, it's for the case when processing is complex and takes a lot of time. MutationObserver runs in a microtask queue so multiple callbacks may still reside in one task, which can lead to very long paint frames and jank.
The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature, which was part of the DOM3 Events specification.
MutationObservers are fired asynchronously but 'soon', which means they fire before other things in the queue, such as layout, paint, or triggered events.
This ameliorates the loss of synchrony, because you don't have to worry about screen flashing or other bad things happening before your observer gets a chance to react.
In developer notes, they talk about an 'end-of-microtask' timing model. I agree this is poorly documented.
I'm going to answer my own question two years later according to the updated DOM spec from WHATWG.
As shown in the spec:
To queue a mutation observer compound microtask, run these steps:
- If mutation observer compound microtask queued flag is set, terminate these steps.
- Set mutation observer compound microtask queued flag.
- Queue a compound microtask to notify mutation observers.
While "Queuing a compound microtask" links to a section in the HTML spec explaining the microtask queue model.
Therefore, we can conclude that MutationObserver
callbacks are fired as microtasks, which are indeed sooner than the task queue tasks as suggested by the answer of @Scott Miles above.
For further understanding of the event loop and processing model, the Event Loop section of the HTML spec would be perfect.
Personally, I'm glad to see that MutationObserver
s are part of the standard and have a well-documented and consistent timing model. With MutationObserver
s supported in most modern browsers, I think they are solid for production use now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With