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.