Quite often I have to benchmark and optimise the render function of projects that I’m working on.
To make it easier I added logTime to my fork of the core Debug package. It just wraps a function and runs console.time(name) and console.timeEnd(name) around it, which prints the evaluation time to the console.
To benchmark something like this:
view : Model -> Html msg
view model =
div
[]
[ renderHeader model
, renderContent model
, renderFooter model
]
I just could do this
view : Model -> Html msg
view model =
div
[]
[ Debug.logTime "header" renderHeader model
, Debug.logTime "content" renderContent model
, Debug.logTime "footer" renderFooter model
]
This will print the time in ms in the console:
Additionally, in Chrome it will also be printed on the Performance timeline which is very useful. Probably other browsers have this too.
This also works well for remote debugging on Android or IOS, checking for performance bottlenecks on lower end devices.
If this is something you would find useful enough to motivate making a PR? Maybe it is already in some other package?
This looks very useful for getting some easy performance information out of programs!
Specifically for views though, this presumably only takes care of VDOM generation, not diffing and applying, right? Surely for the specified use case of optimizing view functions you would care about those more (as those are supposed to be the slow parts).
Yea you are right, only the time of VDOM generation will be counted.
In my experience, the view is where there are something to gain. The times that I have had concerns about performance in my update function, this tool proved me wrong. Usually the update function takes something like 0.1-1 ms to run.
From a user perspective I have found that when you switch to a new page the tolerance of lag is higher. You kind of expect it to take some time. But when you interact with a component on the page (eg. toggle or open something) 100ms feels like forever. This is where it is most important to optimize. Html.lazy can help a lot here.
I guess the time of diffing depends on how much the VDOM has changed. If a lot has changed, the diffing algorithm can bail out early in some situations. However, applying the diff would be directly related to the number of changes.
I started thinking about this, so I created a little test app to compare the VDOM vs. diff vs. apply time. I patched the virtual-dom implementation to log out these three metrics in the console.
Try the test app and see the what numbers you get.
An interesting observation:
You can see how the render times decreases when you click the accordion multiple times. My guess is that this has to do with optimizations by the JIT-compiler.
It is still interesting to see the timings for the view function, even though the entire rendering with the vdom is the real item of interest when optimising performance. After all, the programmer only has control over the view function, and the vdom part is provided by the runtime and in that sense beyond the control of the programmer.
It also strikes me that a pull request to add vdom timing information could be submitted (after the 0.19 release, as there is a context there in which it makes sense).