Ember.js 2.8 and 2.9 Beta Released

Today, the Ember core team is happy to announce two new Ember.js releases – Ember.js 2.8 and Ember.js 2.9 beta.

Ember.js 2.8

Ember.js 2.8 is a minor release with only backwards compatible changes.

LTS Candidate

The Ember.js 2.8 release is considered a release candidate for the LTS (long-term support) channel. As described in the original LTS announcement, the 2.8 branch will be moved into the LTS channel six weeks after today's release. Although we don't anticipate any issues, this process ensures the LTS releases will be rock solid.

Engines

Ember.js 2.8 introduced a new Engines API, which allows multiple logical applications to be composed together into a single application from the user's perspective.

The best way to use this feature in your apps is through the ember-engines addon. To get started, check out the excellent guides written by @trentmwillis.

This release introduced a set of low-level APIs for the core functionality along with the usual semver guarantees. While the ember-engines addon itself remains experimental, the introduction of these public APIs means that ember-engines is now usable with Ember.js 2.8 without feature flags.

Work on engines has proceeded over the past year in both Ember core as well as the addon. Ember's architecture has been enhanced to provide the base classes and hooks needed to support engines. The addon then makes use of these interfaces to provide a smooth experience building and consuming engines.

Until now, none of the engine-related classes and hooks in Ember have been exposed publicly. However, starting with Ember.js 2.8, the following APIs are now public:

Ember.Engine class - The base class for Ember.Application . Its only public interface is related to initializers and instance initializers, which is then inherited by applications.

Ember.EngineInstance class - The base class for Ember.ApplicationInstance .

{{mount}} helper - Allows for the mounting of routeless engines in templates. This helper currently only takes one argument, the name of the engine, e.g. {{mount "chat-engine"}} .

mount router DSL - Allows routable engines to be mounted at a location in a route map.

By making these APIs public, ember-engines and other addons will be able to access them without a feature-flag. By accessing only public interfaces in Ember, an addon won't need to rely on private overrides and can provide as stable an experience as possible.

We predict that engines will grow in popularity once work on lazy loading is complete. By delaying the loading of engines until they're accessed, we can decrease the initial payload size and startup time for applications. If you're interested in helping to implement or test lazy loading of engines, please check out the thorough attack plan written up by @nathanhammond.

Other Notable Features

Enumerable#includes and Array#includes

In an effort to remain in line with ES standards, the methods Enumerable#contains and Array#contains have been deprecated in favor of the new methods Enumerable#includes and Array#includes .

Addon authors should use ember-runtime-enumerable-includes-polyfill to fix the deprecation in a backwards-compatible way.

Thanks to @alexspeller for the RFC that proposed this change.

Thanks as well to @bmeurant for the PR that implemented the change.

Ember.String.isHTMLSafe

The new method Ember.String.isHTMLSafe detects if a string was decorated using Ember.String.htmlSafe .

For example:

1 2 3 4 5 var plainString = ' plain string ' , safeString = Ember.String.htmlSafe( ' <div>someValue</div> ' ); Ember.String.isHTMLSafe(plainString); Ember.String.isHTMLSafe(safeString);

Thanks to @workmanw for the RFC that proposed this new API, as well as the PR that implemented it.

On a related note, please create safe strings with Ember.String.htmlSafe instead of the using the deprecated Ember.Handlebars.SafeString . See the deprecation guide for details.

Ember.Test.checkWaiters

The new method Ember.Test.checkWaiters provides a simple mechanism for test tooling to determine whether all async test waiters have settled. This replaces the intimate API Ember.Test.waiters , which has been removed in Ember.js 2.8.

Thanks to @rwjblue and @krisselden for implementing this method.

For more details on the changes landing in Ember.js 2.8, review the Ember.js 2.8.0 CHANGELOG.

Ember.js 2.9 beta

Ember.js 2.9 beta is also being released today. Per our usual release cadence, it will be released to the stable channel in six weeks.

This release will not introduce any new features or deprecations. Instead, this release will be focused around integrating the Glimmer 2 rendering engine into Ember.

Glimmer 2

In this year's EmberConf keynote, Yehuda mentioned that we are working on a highly optimized rendering engine for Ember called Glimmer 2. A few weeks ago, we announced the Glimmer 2 alpha to invite our community to help test the new engine. Today, we are very excited to announce that the Glimmer 2 engine will be included in the 2.9 beta release.

Compatibility First

As mentioned above, the initial Glimmer 2 integration does not expose any new user-facing features. The primary goal of this release is maximal compatibility – we expect the final release to be a drop-in, completely backwards compatible upgrade for virtually all Ember users.

During the alpha testing period, the Ember core team and our community were laser-focused and worked really hard to achieve this goal. Thanks to all the alpha testers, addon authors and contributors who reported issues or chimed in with patches, we are able to meet our compatibility target and feel confident about including Glimmer 2 with the 2.9 release.

That being said, despite our best efforts and the extensive alpha testing, we still might have gotten a few details wrong, hence the beta releases. We would really appreciate it if you could start testing your applications and report any regressions, if you have not already done so. You may refer to the master issue for a list of known issues.

It's also worth noting that the 2.8-LTS release (when available) will be the final LTS release to include the current-generation rendering engine, which will be supported with critical bugfixes until at least May 2017 and security patches until at least October 2017.

New Template Serialization Format

Glimmer 2 adopted a new serialization format for the precompiled templates. The new serialization format offers a few benefits – among them are reduced byte size (hence download time) and parse time.

Take this simple template for example:

1 Hello {{ name }} ! {{# if isFriday }} Happy Friday!!! {{/ if }}

In Ember.js 2.8, this template compiles into a JavaScript function with 2273 bytes, or 472 bytes minified and gzipped. At the time of writing, Ember.js 2.9 beta compiles the same template into a JSON string with 374 bytes, or 213 bytes minified and gzipped. You can explore the difference in this gist.

There are a few caveats with the previous paragraph. First of all, the details of the templates serialization is a private API that is subject to change anytime and should not be relied on. Second, the reduction varies between templates, depending on various factors such as the number of blocks used in the template. Third, minification and gzip are usually applied to the entire application bundle and they work a bit differently in those environments.

Nevertheless, these numbers offer a good ballpark estimates on what you could expect. From our experience, the reduction generally scales well and holds up in real-world scenarios.

Besides the byte size savings, the JSON serialization format also reduces parse time and allows us to defer the work till the template is actually used.

This is an area that is still being actively worked on, and we expect the serialization format to go through some more changes before the Ember.js 2.9 stable release.

Performance

One of the overarching goals of the Glimmer 2 project is to improve performance in Ember. While compatibility is the immediate priority for this release, performance remains an important secondary consideration.

Our conservative goal for this first release is to avoid introducing any accidental performance regressions. Based on our testing, we have cleared that goal with ample headroom.

As the benefits of Glimmer 2 begin to trickle in, we have already seen noticeable improvements to rendering performance (both initial render and re-rendering). Among other things, the {{link-to}} helper and {{#each}} loops with big lists appear to be significantly faster. Component instantiation has also seen some modest improvement.

However, we have also noticed a performance regression in the pre-render phase. Specifically, we have seen a small increase in the vendor.js byte size and an increased delay before the application gets to render anything. This regression eats into the rendering improvements. We are actively working on these issues and we expect them to be addressed before the final release in Ember 2.9.

Despite the caveats, our data suggest the savings from template byte size and improved rendering performance more than offset the current issues. Therefore, we expect most applications to see an overall improvement in performance upon upgrading to the beta release.

It is worth noting that these observations are recorded from complex production applications maintained by members of the core team (as opposed to isolated synthetic benchmarks). Given the current state of affairs, we are hesitant to circulate premature numbers that are specific to a handful of applications. We plan to perform some thorough analysis as we get closer to the final release.

In the meantime, we encourage you to test the beta release against your own applications. If you notice that certain common patterns have become slower, please report them as bugs. As always – when running performance benchmarks, please make sure you are using the minified production build ( ember.min.js ). The debug builds contain a lot of helpful development aids that impact performance negatively.

Future Work

While this release serves as an important milestone and proving ground for the Glimmer 2 project, we are barely scratching the surface here. One of the informal mandates of the Ember project is "we will keep on shipping", and this is no exception.

The Glimmer 2 engine unlocks a whole new arena of performance optimizations. Once the dust settles, we are committed to keep iterating on performance improvements. Ultimately, our goal is to make the overhead of breaking up an app into small, composable components negligible over time. We are optimistic that there will still be ample headroom for further improvements in this area.

Besides performance, Glimmer 2 has laid a solid foundation for us to build on.

The project originally started when Tom, Yehuda and I spiked on implementing "angle bracket components" in the HTMLBars ("Glimmer 1") engine over a year ago. This exercise highlighted some fundamental misalignments between the current rendering stack and the direction Ember is headed.

While HTMLBars handled basic templating, it left the implementation of many of Ember's view layer features (notably components) up to Ember itself. Not only did it make new features more difficult to implement, it made it hard to implement them efficiently out of the gate.

As Ember has moved towards components and "data-down, actions-up", we wanted to do many optimizations that just weren't a good fit for the HTMLBars architecture. The lessons we learned from the spike ultimately leading us down the journey that is now known as the Glimmer 2 architecture. The underlying technologies are very interesting, but I will save those details for another time.

As an Ember user, you can expect the new engine to unlock some long-awaited features, such as FastBoot rehydration, incremental rendering and a refreshed approach to components once the initial integration is complete.

Thank You!

Since forking HTMLBars, the Glimmer repo has clocked over 850 commits, not to mention the integration effort that happened on the Ember side and also in the wider ecosystem. All of these would not be possible without the help from our community.

Thank you to every one who helped us get here – from the companies who donated employees' time to the individual contributors who made personal sacrifices to make this happen.

For more details on the changes landing in Ember.js 2.9 beta, review the Ember.js 2.9.0-beta.1 CHANGELOG.