AFASSoftware / maquette

Pure and simple virtual DOM library
https://maquettejs.org
MIT License
774 stars 63 forks source link

Ability to manage Events and Schedule Rendering #51

Closed kitsonk closed 4 years ago

kitsonk commented 8 years ago

Context: We have been prototype using Maquette with dgrid considering using it for the next major version. We have found a few things that we see as challenges for us in adopting it. @kfranqueiro, @maier49, and @edhager have been working on the prototyping.

Problem Description

In certain cases, the application is aware that certain DOM Events of which it has listeners for do not equate to any mutations of the DOM, but currently Maquette will always schedule a render on any listener provided via the VDOM.

Also, we are unsure if the intent of Maquette to potentially manage these events. While the code documents the projector option of eventHandlerInterceptor the actual code will always overwrites this option with one that always schedules a render. (We suspect this is a defect)

@pdfernhout brought this up in #31, but we have had some further experience with this.

Impact

We noticed in our prototypes a significant amount of "jank" when the list was scrolled. Part of that "jank" we us actually some coding issues in our implementation and we were able to get the performance to improve to a great degree, but we highly suspect that in certain situations under certain environments, a schedule render for every scroll event would make the performance unacceptable.

Discussion

We suspect the eventHandlerInterceptor is potentially a defect.

On the wider topic though which was discussed in #31. The application "knows" that only an aggregate scroll movement of X actual would cause the DOM to need to be updated and that often takes 10x the DOM events to equal something the application actually cares about, so for 9 of those events, we have recalculated the whole of the VDOM which results in a noop for actual DOM mutations. The feeling I get from the discussion in #31 was "let's discuss real problems, versus potential ones" which, to me, makes a lot of sense. I think we have come up with a use case though that can cause real problems. Implementing a custom eventHandlerInterceptor could resolve this issue (or as suggested in the other ticket, a custom Projector). In both those cases though, it would mean we would have to become the "experts" at VDOM versus and something we are reticent to do.

We hope given a compelling use case, we can find a way to improve Maquette to be able to manage DOM events bubbled up to the application more efficiently.

johan-gorter commented 8 years ago

For now, you can register your scroll event an event using addEventListener from an afterCreate callback. In the event handler you can choose whether you call projector.scheduleRender or not. I still want to build an AdvancedProjector which would be a stand-in replacement for the normal maquette projector which can be instructed not to re-render during event handling.

doublerebel commented 8 years ago

FWIW I've had a really easy time just attaching events to the VDOM parent and letting the events bubble up. Then I just schedule renders on my own as a reaction to my observable model(s). (I'm using SpineJS for the Model and Controller logic and this is how it already works anyway.)

This is a simple example, maybe too abstract: https://github.com/nextorigin/el-borracho-ui/blob/master/src/controllers/queue-filters.coffee

A more complete MVC example can be seen at my helper lib maquette-mapper: https://github.com/nextorigin/maquette-mapper

CitrusFruits commented 4 years ago

Did either AdvancedProjector or a way to opt out of automatic re-rendering in events ever make their way beyond ideation?

The application my team is working on would see significant efficiency improvements if we had greater control over when renders happen. I'd love to help contribute towards a more streamlined solution if it's feasible.

johan-gorter commented 4 years ago

The AdvancedProjector is still an idea. At AFAS we created a special projector that allows measuring the DOM elements and then rerendering to accomodate the available width/height.

We could make a copy of maquette's projector as a separate open source project 'AdvancedMaquetteProjector' that has the needed extension points to fit all our needs. Would this work for you?

CitrusFruits commented 4 years ago

@johan-gorter Yes I think that would be very helpful and would work for us.

johan-gorter commented 4 years ago

We finally got around to creating the advanced projector. This test demonstrates your usecase. Please let me know if it works for you, then I will make a 1.0 release from it. Consider the advanced projector project a community project and we won't mind much if it grows in size, so pull requests to add features are welcome and will be merged and released asap.

johan-gorter commented 4 years ago

@CitrusFruits have you gotten around to testing the advanced projector yet?

CitrusFruits commented 4 years ago

@johan-gorter I apologize, I missed your previous comment. I will test it out today.

CitrusFruits commented 4 years ago

@johan-gorter Yes, the advanced projector fits our needs exactly. Thank you so much!

johan-gorter commented 4 years ago

@CitrusFruits, shall I create a 1.0 release of advanced projector (meaning semver backwards compatibility semantics on the typescript interfaces) and close this issue?

CitrusFruits commented 4 years ago

@johan-gorter That sounds good to me.