Stewart Brodie wrote:
Maciej Stachowiak <[EMAIL PROTECTED]> wrote:

On Jul 16, 2008, at 5:00 PM, Stewart Brodie wrote:

Maciej Stachowiak <[EMAIL PROTECTED]> 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

Reply via email to