We recently released Deveo 3.15. Alongside awesome new features like repository level authorization and configurable password expiration, the release includes several internal improvements. The most prominent improvement is updating our web application to use the recently released Ember.js version 2.10. This blog post describes the performance improvements of the update in Deveo.
Ember's 2.10 release is a significant milestone as it includes the long-awaited Glimmer 2 engine - a ground-up rewrite of Ember's rendering engine. We have been anticipating this release for quite some time, and are happy to reveal the wait was not in vain!
Ember.js and Deveo
Deveo's frontend is a fairly large Ember.js application. To give some insight, we currently have a little over 100 routes with corresponding routes, controllers, and templates, in addition to 382 components. We also utilize Ember Data for persisting our data, and currently, store data to 56 different models.
From the performance perspective, Ember.js has served us quite well so far. However, there are certain views in Deveo that may have lots of data visible at once, and therefore require a lot of components to be rendered during the initial load. In these cases, performance quickly becomes a bottleneck. Luckily for us, this is exactly one of the main goals Glimmer 2 aims to solve - improving the performance of re-rendering and initial rendering. It's worth noting that in Deveo, the majority of bottlenecks are caused by initial renders rather than re-renders.
That being said, we were very eager to finally upgrade to Ember 2.10 and get to test the final release build in practice. The upgrade process was surprisingly seamless, thanks to Ember's core principle of Stability without Stagnation. Internally, we have prepared for this release by keeping up with the stable releases, avoiding the usage of private APIs, and fixing deprecations early on. The only minor issues we bumped into were mostly related to third-party Ember add-ons and small run loop bugs.
We benchmarked the new 2.10 Ember.js release against the 2.9.1 release. The builds were run locally against the same backend and data. Each test run was executed manually in Chrome and the results were inspected using the "Render Performance" tab in Ember Inspector. It's important to benchmark different Ember versions using minified production builds in order to rule out any overhead caused by the debugging features enabled in development builds.
Several benchmarks were conducted, but we'll cover only the two most strenuous ones for sake of keeping things brief. In the first scenario, we created a milestone that contained 500 issues and inspected the initial rendering speed of the view using the cards layout. With this amount of issues, the total number of components rendered for the issues board alone was 1514.
The second test scenario consisted of rendering large diffs in the changesets view. The total amount of components in this test was 1505.
The tests were run 20 and 15 times respectively to minimize the variances.
Our results indicate the new Glimmer 2 rendering engine surpasses the legacy engine in all scenarios. The two previously mentioned scenarios are listed next for comparison.
Scenario 1. Rendering 1514 components, an average of 20 runs:
|Total time (in ms)||1566.24||896.65||~1.75x faster|
Scenario 2: Rendering 1505 components, an average of 15 runs:
|Total time (in ms)||2169.19||1405.18||~1.54x faster|
What a difference! It's important to note that the improvements seen here are consistent across the whole application. Although we do agree the performance is far from optimal in certain scenarios, getting such improvements by simply upgrading to a new Ember version is terrific! In more complex views, we saw improvements well over 2x.
In addition to rendering improvements, the total file size of the core Deveo web application is decreased drastically thanks to the new template compilation output in Ember 2.10. This means faster initial loading times, especially on slower connections:
|Uncompressed size||2.7MB||1.3MB||~2.1x smaller|
|Gzipped size||311KB||202KB||~1.5x smaller|
The results indicate a clear improvement in rendering performance over the previous stable release. It's worth noting that not all the performance optimizations have been unlocked in the 2.10 release in order to maximize compatibility with older Ember versions. Overall, we are very pleased with the results and look forward to future improvements. In addition to the performance improvements, the size of Ember.js applications is also greatly reduced due to the revised template compilation.
As a future work, we are looking into improving the initial rendering performance in certain views by utilizing "svelte rendering" - the practice of avoiding rendering content outside the browser's viewport and rendering only items actually visible to the end-user.
PS. We are looking for a senior Ember.js developer to join our ranks! For more information, see our job ad in Workable.