WinJS 2.0 Listview performance improvements
I published a post about WinJS.Binding.Template and its low rendering performance here last year. It's past. With upcoming WinJS 2.0, there is completely new implementation of templates and it rocks!
It was already demonstrated by Josh Williams on //Build 2013 conference but I wanted to re-check it on my own.
I downloaded my example from last post and upgraded it to new WinJS and run on new OS. I had to fine-tune Template definition (I'll write about few tricks in my next post) and let's see the results.
You can download it here and run the sample.
The results are same as in previous post except WinJS.Binding.Template. All WinJS.Binding.Template related scenarios are much faster than before. In my test scenario they are just 2-3x slower than manual rendering. The template definition is fine tuned to have one-time only binding. But anyway, it's great news!
Let's the see the scenarios and their results. I measured it on Dell XPS12 ultrabook.
This is pure manual approach. The time was from 60 ~ 100ms.
Using WinJS.Binding.Template and its declarative binding
This is declarative approach with manual iterating over the items and rendering them. The time was in range from 210ms ~ 280ms.
It's same as previous just using SampleJS.UI.DataTemplate instead of WinJS.Binding.Template. The time was in range from 160 ~ 250ms
As you can see, using SampleJS.Binding.DataTemplate and its results are very similar to WinJS.Binding.Template. This implies that using DataTemplate is not needed anymore and it's better to migrate to fully supported, more robust, documented and fast enough WinJS.Binding.Temlate. Thanks WinJS guys!
So let's see closer what WinJS guys did.
WinJS.Binding.Template rendering details
Here is the template definition:
When rendering WinJS.Binding.Template, its render method is autogenerated by TemplateCompiler on the fly in the runtime and is fully optimized. Here it is:
The main performance gain is that the rendering is split into 2 phases by default! It's done by the template compiler. In our case we use only one-time binding so the template rendering is optimized to use only the first rendering phase. After constructing HTML string it's inserted into DOM. It's done by the code between lines 59 ~ 63.
But we can go further. There is still a space for further performance improvements. Options:
- use cloning the node instead of creating string and inserting it into the DOM
- batch HTML string and insert them at once
I extracted the "hearth" of the rendering method (lines 59 ~ 63) and measured it.
The results are expected. Cloning nodes is faster than constructing HTML and inserting it into DOM. But it depends on the amount of data. In real world scenarios the template is used to render more than several items. So I would keep strings because the fasted solution is to batch strings and render them at once. The result is almost 2x faster than manual rendering! and almost 8x faster than current rendering autogenerated method.
Let's see the code:
It could be probably implemented in the next WinJS 3.0 template rendering method so that inserting generated HTML string into DOM could be batched in very similar way its done in the ListView render optimization sample.
Here is a gist of the template rendering with batching the generated HTML.
That's all for now.