W3C home > Mailing lists > Public > public-webapps@w3.org > July to September 2011

Re: DOM Mutation Events Replacement: When to deliver mutations

From: Rafael Weinstein <rafaelw@google.com>
Date: Wed, 10 Aug 2011 17:51:03 -0700
Message-ID: <CABMdHiQaXjq1Ga23LyZkMAmB3hnOefEmpsMLnLa=T0R6NkeBww@mail.gmail.com>
To: Webapps WG <public-webapps@w3.org>
Ok. Being a proponent, here's my further (opinionated) support for
Option 3 and criticism for Option 2.

On Wed, Aug 10, 2011 at 5:44 PM, Rafael Weinstein <rafaelw@google.com> 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.
> -------
> 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.


-The timing delays delivery just long enough to guarantee that DOM
operations don't have to worry about having their work interfered
with, but encourages application script to leave itself exposed to
exactly the same risk.

-The semantics of delivery are inconsistent. Delivery of mutations is
synchronous if calling operation is performed outside of a mutation
callback and async if performed inside a mutation callback.

> 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.

-Creates (and requires use of -- creates a "pit of success") a time to
run which is ideal in two ways:

1) Performance: The main script is finished doing its work. The
observer can minimize work by reacting to only the net-effect of what
happened. I.e. not do work in intermediate states which ultimately
become irrelevant. E.g. a widget library which needs to "destruct"
widgets which are removed from the document. If a widget is removed
but later added elsewhere in the same script event, the library would
prefer to avoid destructing the widget and just allow it to be moved.

2) Correctness: The observer isn't at risk for attempting to act when
the main script has put the DOM (temporarily) in an inconsistent
state. E.g. a templating library which depends upon the value of two
attributes of a single element. If script wishes to change both values
but cannot do so without creating a temporarily nonsensical state, the
library would prefer not to have to react to the nonsensical state and
simply wait for the consistent (final) state.

To be fair to Option 2, it doesn't preclude these (but it isn't
sufficient -- a separate ability to schedule work at the end of the
Task would be required).

-Behaves quite differently from the current mutation events.
Received on Thursday, 11 August 2011 00:51:27 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 11 February 2015 14:36:52 UTC