ryansolid / dom-expressions

A Fine-Grained Runtime for Performant DOM Rendering
MIT License
858 stars 125 forks source link

Improvements to delegated events and non-delegated events added via addEventListener #254

Closed titoBouzout closed 11 months ago

titoBouzout commented 1 year ago

Essentially, this makes of node[$$${name}] an array. The motivation is that using a delegated event in an element effectively gets rid of the last added event, instead of appending to a list of events added. If we wanted to add many onclick handlers, we will have to resort to native events, which is a pity.

Consider the following, whenever we click the div it will output hi 2, as adding the event removes the first onClick.

 <div
      onClick={() => console.log("hi 1")}
      ref={(element) => {
        onMount(() => {
          addEventListener(element, "click", () => console.log("hi 2"), true);
        });
      }}
    >
      click me
    </div>

Playground: https://playground.solidjs.com/anonymous/9b7e2d2e-625f-4774-81d1-67c1dbeb9d7a

As for the Native events, I have reused/added a similar logic to the delegated ones. The motivation is to add and reuse only 1 listener and dispatch it as many times as needed to anyone wanting to listen to it. As the behaviour is basically the same as delegated events, I believe it's a nice optimization. Which also includes the in place optimization of using the array for binding without actually binding, that delegated events use.

Considerations:

Thanks!

ryansolid commented 1 year ago

We avoided arrays painstakingly for memory/performance overhead. I need to measure this. Mostly that this was an internal API for JSX and now is being used more generally which is the only reason this is a problem. As a JSX helper this isn't necessary. But I understand the desire here, but at a certain point probably need to evaluate the performance of delegation in general.