DOM Mutation Events seemed like a great idea at the time – as web developers create a more dynamic web it seems natural that we would welcome the ability to listen for changes in the DOM and react to them. In practice however DOM Mutation Events were a major performance and stability issue and have been deprecated for over a year.

The original idea behind DOM Mutation Events is still appealing, however, and so in September 2011 a group of Google and Mozilla engineers announced a new proposal that would offer similar functionality with improved performance: DOM MutationObserver. This new DOM Api is available in Firefox and Webkit nightly builds, as well as Chrome 18.

The key advantage to this new specification over the deprecated DOM Mutation Events spec is one of efficiency. If you are observing a node for changes, your callback will not be fired until the DOM has finished changing. When the callback is triggered, it is supplied a list of the changes to the DOM, which you can then loop through and choose to react to.

This also means that any code you write will need to process the observer results in order to react to the changes you are looking for. Here is a compact example of an observer that listens for changes in an editable ordered list:

If you play with the live example, you’ll notice some quirks in behaviour, in particular that the callback is triggered when you press enter in each li, in particular when the user action results in a node being added or removed from the DOM. This is an important distinction to be made from other techniques such as binding events to key presses or more common events like ‘click’. MutationObservers work differently from these techniques because they are triggered by changes in the DOM itself, not by events generated either via JS or user interaction.

So what are these good for?

I don’t expect most JS hackers are going to run out right now and start adding mutation observers to their code. Probably the biggest audience for this new api are the people that write JS frameworks, mainly to solve problems and create interactions they could not have done previously, or at least not with reasonable performance. Another use case would be situations where you are using frameworks that manipulate the DOM and need to react to these modifications efficiently ( and without setTimeout hacks! ).

Another common use of the Dom Mutation Events api is in browser extensions, and in the next week or so I’m going to publish a follow-up post on how MutationObservers are particularly useful when interacting with web content in a Firefox Add-on.

As far as the API /design/ the original API seems far more beautiful in it’s design and I can sincerely not see how this API got through… I mean, I understand some of the flaws of the original model, but that doesn’t change that what happened where *in essence* events. I mean, rather than some odd new object it could have been made into a document only event. And the new vocabulary etc. could have been implemented within the event data as well without all this random new stuff. :'(

I think the main argument against anything like the old api ( besides the differing implementation issues Smaug rightly pointed out ) is just that it was far too difficult to use DOM Mutation Events in a performant way, particularly given very ‘active’ sites like Gmail.

The original mutation events API has never been defined properly and browsers implement various parts of it in different ways. It is also slow and has caused lots of crash bugs in the implementations.
The new API was designed to be faster, run js callbacks less often and at
“stable”, exactly defined time. (Currently the new API implementations are 5-10x faster than the old API)

Adding some API to document was discussed but there are cases when it doesn’t work well (for example if you move nodes from a document to another and back)

This is a terrible replacement for Mutation events. It looks like it was lifted from another language. I really have a hard time believing mutation events caused performance issues, unless the engineers who implemented them did something lazy, like fire the event even when they’re are no listeners bound to the event.

The right solution would have been to only fire the event if a listener is bound. The API above is not consistent with The DOM node model and to be honest doesn’t look like it belongs in a JavaScript application. The API is clunky and requires a lot of extra code.

While Mutation Events can be used without impacting performance much, it is far too easy given their api to create a pathological case. As well, the events api has never been implemented well across all browsers, making cross-browser use difficult for developers for years. See this post for a more detailed evisceration of Events:

I agree that MutationObservers as an API does not feel very convenient, however it is hard to say, given how the DOM can be mutate d by JS code how to do it better without running into the problems we’ve already had with events.

This is really cool. Correct me if I’m wrong, but it seems I must specify each and every element I’d like to observe for change?

Is there a reason I can’t just watch the entire DOM? My use-case is that I’m creating a script that would be used on sites that I’m not personally developing, and I’d really like to respond when any piece of the user interface changes.

please can any one help me, we use onPropertyChange in more than 1000 times in our projects and now we have problem with chrome and and others, we using this event only to call some function in case the value of the textbox value element change by none user action (DOM level change), so how can solve this problem please help me on how to code, as i could not understand above example
Thanks

Is there a way to view the actual attribute and value upon change? Right now i’m only seeing type : “attributes” and attributeName : “style” but it would be truly helpful to also know which style changed and what’s it’s new (or old) value is.
Thanks