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

Re: [D3E] Possible Changes to Mutation Events

From: Jonas Sicking <jonas@sicking.cc>
Date: Mon, 21 Jul 2008 17:02:08 -0700
Message-ID: <48852380.7030706@sicking.cc>
To: Stewart Brodie <stewart.brodie@antplc.com>
CC: Maciej Stachowiak <mjs@apple.com>, Laurens Holst <lholst@students.cs.uu.nl>, Doug Schepers <schepers@w3.org>, public-webapps@w3.org

Stewart Brodie wrote:
> Maciej Stachowiak <mjs@apple.com> wrote:
> 
>> On Jul 16, 2008, at 5:00 PM, Stewart Brodie wrote:
>>
>>> Maciej Stachowiak <mjs@apple.com> wrote:
>>>> On Jul 16, 2008, at 2:03 PM, Stewart Brodie wrote:
>>>>
>>>>> I agree with all that, but it's not the whole story, because making
>>>>> this change has potentially severe consequences for memory usage if
>>>>> you start moving large subtrees around within a document.  Just how
>>>>> long is the event queue allowed to get?
>>>> It will only grow without bound if every mutation event handler in
>>>> turn modifies the DOM itself, or if a compound DOM operation is
>>>> unbounded.
>>> Unbounded queueing is a real concern.  Having said that, the current
>>> situation is that we have unbounded recursion, which is equally
>>> unacceptable, although the recursion depth is at least defined by the
>>> number of recursive calls made by the event listeners, whereas the queue
>>> length is dependent on the number of nodes in the affected subtree,
>>> which is likely to be substantially greater.
>> Can you describe a plausible scenario where growth of the mutation event
>> queue would be a significant issue? You've said repeatedly you are worried
>> about it but have not given an example of when this might happen. Are you
>> talking about the kind of programmer error that results in an infinite
>> loop?
> 
> [Many apologies for the delayed reply]
> 
> The worst case I can think of is Node.replaceChild() where the removed child
> is a large subtree and the new child is a large subtree that's attached
> somewhere else in the document.  This sort of content is easily feasible in
> the sort of UI applications that we have to support (for example, a TV
> electronic programme guide), and yet the memory we have available is
> severely constrained.
> 
> If each subtree contains just 100 nodes, that's 303 events to be queued.
> Even if the new subtree is not attached, that's still 203 events.  What
> happens if we have no memory left in which to queue these events?

So how much memory are these 303 events compared to the 200 nodes that 
are involved in the mutation? I would expect it to be pretty small.

My point is that it's easy to create a scenario where most algorithms 
consume a lot of data in absolute terms. But if it requires that large 
amounts of data is already being consumed then this doesn't seem like a 
big practical problem.

I would actually argue that the problem here is that the 
DOMNodeRemovedFromDocument event is pretty insanely defined. The rest is 
just side effects from that. This is why we haven't implemented it in 
mozilla as of yet.

> Concentrating on the removal side, currently, I have to queue 0 events, and
> I can optimise away DOMNodeRemovedFromDocument completely, usually. However,
> I have to ensure that the detached node and its parent are still valid after
> the dispatch of DOMNodeRemoved.  With these changes, I could only optimise
> away the events if *neither* DOMNodeRemoved or DOMNodeRemovedFromDocument
> have any listeners.  Sure, the DNRFD events would get optimised out at the
> point of dispatch, but I've had to store a whole load of information in the
> meantime.

Hmm.. this is indeed a problem. I definitely want to be able to optimize 
away most of the mutation code if there isn't someone actually listening 
to these events.

One way to fix it would be to state that if no listeners are registered 
for an event by the time it is scheduled, an implementation is allowed 
to not fire the event at all, even if a listener got registered before 
the event would have actually fired.

It seems like it's a very odd edge case where anyone would notice a 
difference at all. It requires that one mutation event listener 
registers another listener for another event.

It'd be ugly, but I can't think of anything better really.

> The alternative would be to queue a promise to generate the event for every
> node in the subtree, but that promise would end up being fulfilled based on
> the state of the tree after DOMNodeRemoved listeners had been executed.
> However, it would reduce the likelihood of memory problems dramatically.

Yes, noone is saying that you need to actually create the actual event 
objects until it's needed.

/ Jonas
Received on Tuesday, 22 July 2008 00:03:47 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:27 GMT