natefaubion / purescript-spork

Elm-like for PureScript
MIT License
157 stars 9 forks source link

Naive question about performance #29

Closed paluh closed 5 years ago

paluh commented 5 years ago

Hi,

Thanks for writing spork! It is really cool!

It's probably a naive question as I don't have any knowledge about vdom internals, but I want to ask if vdom is going to diff Html node in subsequent renders if it will be the same value returned from memoized render.

For example, I want to know if in case of scene containing many, many objects which are static and for which I can memoize render and an object which is going to be dragged (so its Html node value changes on mouse move) is my FPS ratio going to decrease with increasing number of static objects?

natefaubion commented 5 years ago

halogen-vdom doesn't do any optimizations on it's own, however you can achieve the same thing with Spork's memoization primitives.

static :: forall a. Html a -> Html a
static h = memoized eq (const h) unit

staticNode :: forall a. Html a
staticNode = static $ H.div ...

However, if you have many nodes, and you can drag them, then they aren't actually static (or at least in a way where this optimization makes sense), and you'd want to use something like lazy or memoized in a way that makes sense for your scene.

natefaubion commented 5 years ago

Perhaps there could be an additional memoization primitive:

static :: forall a. Html Void -> Html a

In which case this primitive could always skip building new nodes even in the presence of map.

paluh commented 5 years ago

Thanks for your response and suggestions!

Sorry if these are stupid questions. Probably I completely misunderstand mechanics behind vdom diffing... ;-)

However, if you have many nodes, and you can drag them, then they aren't actually static (...)

I'm considering them "static" during "dragging" operation. I want to be able to optimize resource usage during this phase and return two static nodes (above and below) for all objects beside the one being dragged and change only Html value related to this moving object.

If I perform subsequent renders during "dragging" and have most of the scene as these two staticNodes (with many, many children) and only a single sibling element with changing position do size of this static nodes influence overall performance of dragging / rendering (I mean FPS here)? Would "spork / vdom perform" any diffing or computation on these staticNodes to create new DOM version of a scene or it will know that these pieces are exactly the same as on "previous frame" and ignore them?

Perhaps there could be an additional memoization primitive (...)

This is really cool idea!

natefaubion commented 5 years ago

Yes, as long as above and below are truly static (that is they aren't initialized dynamically in some other render function) and you do what I've suggested, then they will not be diffed. As I hinted at, but did not clarify, this does not hold when utilizing the Functor instance of Html. That's because it has to traverse down to the property leaves at some point with the updated continuation, which requires building new nodes.

paluh commented 5 years ago

Thanks for clarification and... for all your amazing Purescript related Stuff!