In a project I’m working on I tried the following approach to do animations: store an animationClock : Float
value in the top-level module and pass it down to the views that need it. This allows to not add an onAnimationFrame
subscription each time I need an animation, but to use it only once at the top level.
Unfortunately, if I need animations everywhere and pass animationClock
to most of the parts of the app, this approach basically makes Html.Lazy
useless (because the value changes every frame), and the entire view tree (or most of it) must be recalculated on every frame.
It is still fast – I can’t really notice any performance issues visually. But since the view is recalculated on every frame, I can see high CPU usage all the time. To optimize this, I need to find a way to disable the subscription when no animations are running. It’s not that simple, for example some of the views that use animations are just stateless functions like spinner : Animation.Clock -> Element msg
that show a loading spinner that just spins forever. So to disable the subscription I need to somehow know if there are any spinners rendered at the moment (and other views that require an animation).
If we used a similar technique like Svelte use (if I understand it correctly) we could evaluate the application’s view
function only once during the compilation and detect which parts of it are static or dynamic, and changes to which parts of the Model
affect which parts of the view
. In this world there would be no need to do any optimizations in my example above, moreover I think Html.Lazy
would not be needed anymore. Of course it’s not an easy task because it’s not possible to implement this on elm/virtual-dom
level and it requires changes to the compiler, but would be cool