@tjohn and I have been comparing Angular and Ember over the last week and were quite surprised at the performance difference when rendering large lists. The TL;DR from our findings was that Ember is roughly 5x slower than Angular.
I am aware that when rendering large lists the recommended solution is to use List View. However List View is cumbersome to use when items are variable size or displayed in rows and columns. We think that lists of the same size should at least have comparable performance.
We’ve built a sample application that renders a list of items as similarly as we think possible. We captured metrics for rendering lists of the following sizes (10, 100, 1000, 10 000). The metrics were captured via the timeline in the Chrome developer tools.
These were the steps we took
- Enter the number of items in the textbox
- Start recording
- Clicked “Render” button
- Stop recording when all the items are displayed
- Look at the click event and record the CPU time
This may not be a fair comparison because Angular attaches each item into the DOM one by one. This means that the browser takes longer to layout. We think Angular could optimize this by building a fragment of all items before inserting them. The key thing to note is that Angular allocates much less memory and performs fewer garbage collections during the rendering phase.
For example when rendering 10 000 items the following images of the chrome dev tools highlight the difference in memory allocation and cleanup. The current Ember implementation is very memory intensive as shown by our investigation.
We dived into the Ember rendering pipeline and noted that it is based on string concatenation . As a collection view enumerates its children, it generates a string representation of each child view and appends them to the buffer of the collection view. The string buffer is then converted into to a document fragment before appending itself to the DOM.
We are proposing that the render buffer should be a document fragment. Some benchmarks indicate that document fragments are the fastest way to build and append a DOM tree.
As we only have a surface level knowledge of the Ember rendering pipeline are there any reasons the original buffer was not implemented as a document fragment? And do you see any flaws with our proposed solution?