AFASSoftware / maquette

Pure and simple virtual DOM library

Home Page:https://maquettejs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow changing event handlers

johan-gorter opened this issue · comments

To make maquette more pure and simple, we want to allow event handlers that are recreated on every render. Although reusing event handlers would always benefit performance, we think that we can make the performance penalty of updating them negligible. This is done without updating the DOM with new event handlers or introducing the overhead of a virtual event system.

This is one of our ideas for maquette 3

Would be a nice improvement ;) I guess you plan to implement a DOM delegator?

@sprat You can see the algorithm that we use here. I do not know of any framework that uses the same approach, but we are very pleased with it.

I've not looked at your code yet but I once looked into the code of virtual-dom's dom-delegator: it attaches a DOM event handler to the document (in capture-phase but I can't remember why) and uses DOM event bubbling to receive the event and the target DOM node. The corresponding virtual dom node is stored as an attribute of the DOM node in virtual-dom so it's easy to find the event handlers attached to the virtual-dom node. So essentially, changing an event-handler in virtual-dom is just replacing a property in the events object of the virtual dom node, so it's very cheap.

We choose not to use a delegator, because this would mean we have to wrap the native events in new events to set the currentTarget to the right element. Storing a VNode at a DOM node would mean we would have to update all dom nodes on every render with new VNodes.

What we did is instead of attaching the the event handler that is provided in the VNode, we add a generic event handler. This generic event handler, when invoked, travels up throught the parentElements en then uses that path to travel down on the VNode tree, finding the right VNode and then invoke the right handler.

In fact, you don't have to wrap the native events: the dom-delegator is a generic handler that capture all the events, map the target DOM node of an event to the corresponding VNode and call the VNode handler. The DOM->VNode mapping is done by storing reference to the VNode into the DOM node. And you just have to update the DOM nodes that have changed (including the VNodes that just have changed their event handlers).

IMO, traversing the DOM and VNode tree is just another way to map a DOM node to a VNode, but without storing the VNode into the DOM node. So basically, your approach is similar to virtual-dom's one, as far as I understand.