Re: Mutation Observers: a replacement for DOM Mutation Events

On 13/10/11 12:34 AM, Olli Pettay wrote:
> On 10/12/2011 02:00 PM, Sean Hogan wrote:
>> On 12/10/11 3:26 AM, Tab Atkins Jr. wrote:
>>> On Mon, Oct 10, 2011 at 7:51 PM, Sean Hogan<shogun70@westnet.com.au>
>>> wrote:
>>>> On 24/09/11 7:16 AM, Adam Klein wrote:
>>>>> - Is free of the faults of the existing Mutation Events mechanism
>>>>> (enumerated in detail here:
>>>>> http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) 
>>>>>
>>>>>
>>>> A simpler solution that is free from the faults listed in that email
>>>> would
>>>> be to have (at max) one mutation observer for the whole page 
>>>> context. I
>>>> guess this would be called at the end of the task or immediately
>>>> before page
>>>> reflows.
>>>>
>>>> If a js lib (or multiple libs) want to provide finer grained mutation
>>>> handling then let them work out the details.
>>> That seems unworkably restrictive. It's very easy to imagine multiple
>>> libraries listening for different kinds of things at the same time.
>>> Libraries would just end up re-implementing event distribution, which
>>> is something we can avoid by doing it correctly now.
>>
>> This proposal doesn't entirely avoid the issue of event distribution.
>> There is no equivalent of event.stopPropagation() and hence no way to
>> prevent mutation records being delivered to observers. The observers may
>> have to be written with this is in mind.
>>
>> For example, what if two observers can potentially handle the same
>> mutation - which one should handle it?
> Both. Or the observers need to somehow communicate with each others to 
> decide who handles it. This is no different to event listeners.
> Event listeners don't know if there are other listeners before them or 
> after them. You can have several listeners in the same target and 
> different script libraries may have added them without knowing about 
> each others.
>

It is different to event listeners. The following

     document.body.addEventListener("DOMAttrModified", handler, false);
     
document.getElementById("target").addEventListener("DOMAttrModified", 
preferred_handler, false);

allows preferred_handler to prevent handler receiving the event. The 
observer solution (something like):

     handler_observer.observe(document.body, ...);
     
preferred_handler_observer.observe(document.getElementById("target"), ...);

does not.

My argument may be weak, but you don't help this discussion by providing 
an even weaker argument to counter it.

>
>
>>
>> Alternatively, some code might respond to an attribute by adding content
>> to the DOM. What if there are mutation listeners that could respond to
>> that added content? Is it desired that they ignore or handle it?
>>
>> Another pattern that doesn't seem to be reliably handled is mutations
>> within DOM fragments that are temporarily removed from the document.
>> That is:
>> - if the fragment always remains in the document then all mutations can
>> be monitored by observers on the document (or document.body), but
>> - if the fragment is removed from the document followed by mutation
>> observers being called, then any further mutations won't be delivered to
>> the observers, even when the fragment is reinserted into the document.
> >
> > The exact behavior in this scenario depends on whether mutations
> > complete within one microtask or more than one
>
> If the modifications to the fragment are done during the same 
> microtask, then the observer will just get notified about those 
> modifications. If in different microtask, then observer should observe
> that fragment (so when the fragment is removed from document, 
> observer.observe(root_of_fragement, options) should be called.).
>
> If there was just a global - per document observers, those wouldn't
> handle all the cases when node is adopted to and from other documents.

I didn't think of that but I don't think it's a good idea anyway. If 
observing mutations in another document is required then use their per 
document observer. Or have I missed something?

> Also, such observers would make all the DOM mutations slower, since
> the callback would need to be called all the time.
>

Yes, but you have to remember that many DOM mutations necessitate page 
reflow, and the cost of mutation listeners has to be weighed against 
that, not the execution time of one DOM operation.

In the extreme case, per document observers won't be any slower than

     observer.observe(document, all_options);


> The proposed API allows one to restrict mutation observing to certain 
> set of nodes. Mutations outside that set can be kept as fast as having 
> no mutationobservers at all.
> And also, since the observed set can expand, and isn't limited to same 
> document handling, it can easily handle cases when nodes are moved to 
> some other document.
>

My main reservation towards the proposal is its complexity - it promises 
a lot and I will be surprised if it is as trivial to implement as you 
have implied. Even then, I'm expecting that it isn't the improvement 
(over the status-quo) that everyone is speculating. It's great that 
there is going to be an implementation real-soon-now so that my concerns 
can be allayed / confirmed.

Sean

Received on Thursday, 13 October 2011 02:52:14 UTC