Re: DOM Mutation Events Replacement: When to deliver mutations

On 08/11/2011 03:44 AM, Rafael Weinstein wrote:
> Although everyone seems to agree that mutations should be delivered
> after the DOM operations which generated them complete, the question
> remains:
>
>    When, exactly, should mutations be delivered?
>
> The four options I'm aware of are:
>
> 1) Immediately - i.e. while the operation is underway. [Note: This is
> how current DOM Mutation events work].
>
> 2) Upon completion of the "outer-most" DOM operation. i.e. Immediately
> before a the lowest-on-the-stack DOM operation returns, but after it
> has done all of its work.
>
> 3) At the end of the current Task. i.e. immediately before the UA is
> about to fetch a new Task to run.
>
> 4) Scheduled as a future Task. i.e. fully async.
>
> -------
>
> Discussion:
>
> Options 1&  4 are don't seem to have any proponents that I know of, so briefly:
>
> Option 1, Immediately:
>
> Pro:
> -It's conceptually the easiest thing to understand. The following *always* hold:
>    -For calling code: When any DOM operation I make completes, all
> observers will have run.
>    -For notified code: If I'm being called, the operation which caused
> this is below me on the stack.
>
> Con:
> -Because mutations must be delivered for some DOM operations before
> the operation is complete, UAs must tolerate all ways in which script
> may invalidate their assumptions before they do further work.
>
>
> Option 4, Scheduled as a future Task:
>
> Pro:
> -Conceptually easy to understand
> -Easy to implement.
>
> Con:
> -It's too late. Most use cases for mutation observation require that
> observers run before a paint occurs. E.g. a widget library which
> watches for special attributes. Script may create a<div
> class="FooButton">  and an observer will react to this by decorating
> the div as a FooButton. It is unacceptable (creates visual
> artifacts/flickering) to have the div be painted before the widget
> library has decorated it as a FooButton.
>
> Both of these options appear to be non-starters. Option 1 has been
> shown by experience to be an unreasonable implementation burden for
> UAs. Option 4 clearly doesn't handle properly important use cases.
>


When I proposed watchSelector [2], the idea was clearly to propose an option that provided semantics similar to Option 4 as described here.
The primary benefits I sought were:
Pros:
* batching - allow a script to operate on the DOM's cumulative changes, vs. incremental changes.
* filtering - provide a well-known mechanism for quickly and precisely identifying the nodes in the document that should be observed.
* performance - fully async has the potential to very fast to implement

I think the filtering benefit could be extended to either Option 2 or 3.
I prefer Option 3 because if offer a larger opportunity for batching.

Cons:
* See previously stated use case as argument against this approach
* The approach didn't account for node "movement" within the document (reparenting of elements).
* The approach (using Selectors) was deemed "too risky" because web developers can provide complex selectors that make running the mutation detection algorithm expensive for the UA.

I still like the idea of using selectors, and after a conversation with Jonas, I realized that the perf concern can be eliminated yet preserve the filtering benefit by only allowing what CSS calls "simple selectors" [3], which are basically attribute/class/id selectors w/out combinators. Text mutations are generally in an entirely different category (primarily editing scenarios), and obviously won't work with Selectors. Additionally, the context information for text nodes is different than for elements, which leads me to believe that for text mutations, some different API may be necessary.



> -------
>
> Options 2&  3 have proponents. Since I'm one of them (a proponent),
> I'll just summarize the main *pro* arguments for each and invite those
> who wish (including myself), to weigh in with further support or
> criticism in follow-on emails.
>
>
> Option 2: Upon completion of the "outer-most" DOM operation.
>
> Pro:
> -It's conceptually close to fully synchronous. For simple uses
> (specifically, setting aside the case of making DOM operations within
> a mutation callback), it has the advantages of Option 1, without its
> disadvantages. Because of this, it's similar to the behavior of
> current Mutation Events.
>

Pros:
* May be very easy to migrate existing sites/apps from current mutation events code to this option. If the message of the new mutation events model we create is "we finally fixed mutation events, please use this new code instead" then the easier we make the transition to the new model the better.

However, in my experience websites and apps don't just migrate because the new model is available. Web sites generally follow the pattern: "if it isn't broke, don't fix it." To me, this means that classic Mutation events aren't going away, and unless the new model provides significant advantages over the old model, legacy code just won't update. It's really the new code that we're targeting, and that makes it more acceptable to design for a model that has greater potential to economize mutations by batching yielding better performance, i.e., Option 3.
 

> Option 3: At the end of the current Task.
>
> Pro:
> -No code is at risk for having its assumptions invalidated while it is
> trying to do work. All participants (main application script,
> libraries which are implemented using DOM mutation observation) are
> allowed to complete whatever work (DOM operations) they wish before
> another participant starts doing work.
>
>

I'm also a proponent of Option 3. I like the idea of getting a changelist upon which my code can act after all the previous script has had a chance to make its changes. A particular Con with this approach is that the notifications for mutations are coming out-of-context from which the actually occurred. Careful consideration should be given to the context associated with the changelist, so that callbacks handling the changelist do not need to perform too much unnecessary context-establishment in order to do their work.


[2] http://www.w3.org/2008/webapps/wiki/MutationReplacement
[3] http://www.w3.org/TR/css3-selectors/#simple-selectors


-Travis

Received on Wednesday, 7 September 2011 22:57:58 UTC