In this article, we'll explore what's new in Angular 9. Although the versioning change from 8 to 9 seems like a big step, v9 is an evolutionary release (and includes mostly bug fixes). However, there are several interesting new Angular 9 features.
Here' we'll discuss:
- Built-in Angular Features
- Mature Development with Angular
- Understanding Angular View Engines
- Angular Ivy Solves Long-Standing Problems
- Angular Ivy and Mobile
- Selector-less Directives
- Angular Diagnostics Improvements
- Internationalization with Angular Ivy
- DI and Type-Safe in Angular 9
- Dependency Injection Changes in Angular Core
- Angular Benchmarks (Angular 8.2.7 vs. 9.0.0-next.5)
Angular is one of the most prominent open-source frameworks for building web and mobile applications. Developed by Google, Angular has evolved over the years into a comprehensive development framework that includes all of the tools and components required to build a web app. Angular follows a clear roadmap, with a new major version of Angular released every six months. The Angular team works thoughtfully so that the API doesn’t need to change (or at least not as drastically as it did from Angular 1 to 2). This is a good thing, it keeps things up-to-date with the latest best practices and latest features supported by TypeScript or JavaScript.
We've covered Angular 8 in other articles, along with tips for using our Wijmo Angular UI components and other aspects of development with Angular. Here, we’ll start by looking at one of the problems that plagued previous versions of Angular: large bundle files that have negatively impacted download times and, as a consequence, application performance.
The big new feature we'll dive into is the Ivy compiler. We'll explain what Ivy does and why it's actually an important feature for the future of Angular. Spoiler alert: it solves some of the problems with large bundles and application performance.
We'll touch on a few other new features, including selector-less bindings and internationalization support. You'll see why we're calling this an evolutionary release rather than revolutionary.
Finally, we’ll run some benchmark tests to compare performance between Angular 8 and a pre-release version of Angular 9. The latest Angular 9 Release Candidate (9.0.0.rc-9) was posted recently, and we’ve updated our benchmarks to include this latest release.
JavaScript Bundles and Performance
One of the ongoing problems with previous Angular versions is the relatively large file size of the app — more precisely, the file size of the generated JavaScript bundles. If you compare Angular to other libraries such as React or Vue.js, the Angular app is significantly bigger.
At runtime, you probably won’t feel the difference. While Angular runtime performance is good, the loading can take longer because even a simple app can be relatively large.
The size of the JavaScript bundles also hints at another problem: there's more to learn with Angular because Angular is a complete framework with many built-in developer tools, while other JavaScript libraries are more focused on components.
So what could the Angular team do to mitigate the problems stemming from the large bundle files in earlier Angular versions?
Understanding Angular ViewEngine
Before Angular 8, the framework relied exclusively on ViewEngine (sometimes referred to as the "VE") to build and render code in browsers. Angular components are written using the TypeScript language. TypeScript is a superset of JavaScript, and we use a compiler or "transpiler" to render TypeScript into a dialect of JavaScript that runs in the browser. Angular historically has relied on ViewEngine to do this transpiling from TypeScript code into JavaScript.
The Angular ViewEngine takes the templates and components and translates them into regular HTML and JavaScript so that the browser can interpret and display them.
Angular Ivy Solves Long-standing Problems
One of the most significant features that shipped with Angular 8 was the opt-in Ivy preview. Ivy is Angular’s new internal build and render pipeline. The renderer is the engine that takes the instructions you input into the Angular components with the templates and then translates them into instructions that change the DOM (Document Object Model).
The Ivy compiler is hidden away, and replacing ViewEngine with Ivy does not change the way you work with Angular. But this change does have a significant impact on the code that’s being generated.
The Angular 8 preview lets users play around with Ivy. With Angular 9, Ivy is the standard renderer. If a renderer is more efficient or easier to implement, that means you can ship less code because fewer instructions are required, and that’s the purpose of Ivy.
Ivy yields much smaller JavaScript bundles, so Ivy solves Angular’s bundle weaknesses. Ivy will be a game-changer because it brings Angular applications to a whole new level in terms of performance and size.
Ivy doesn’t change the way Angular is used, but it does change how the app is generated. The Angular team has focused on initiatives like the differential loading of modern JavaScript, which shipped with Angular . This means that different polyfill bundles are created and deployed together. At runtime, only the polyfills that are required for the specific browser are loaded, thus leading to less code being downloaded.
Angular Ivy and Faster Mobile Apps
Smartphones and other mobile devices account for about half of the website traffic worldwide. A considerable percentage of these mobile devices access web pages from locations that suffer from slow internet connections.
Developers can redesign existing apps to reduce the size of the downloadable assets and enhance the mobile user experience, but these changes can be difficult, expensive, and introduce unforeseen risks to their projects.
By reducing the size of JavaScript bundles, Ivy becomes a welcome improvement for developers trying to speed up application startup.
Putting Ivy to Work
In Angular 9, the new Ivy compiler will finally be the default, so Angular apps built with Ivy will be faster and more efficient.
In Angular 8, Ivy was optional, so you had to explicitly enable it by adding the following lines to the tsconfig.json file in the project folder:
"angularCompilerOptions": {
"enableIvy": true
}
And then you had to run the compiler by executing the ngc command inside the project folder:
node_modules/.bin/ngc
In Angular 9, setting the enableIvy option in the tsconfig.json file is no longer needed since the Ivy renderer is the default.
Selector-less Directives
One feature missing from the Angular 8 Ivy preview that had been available in ViewEngine was the ability to use selector-less directives as base classes.
With Angular 9, this feature has been added to Ivy so that developers get the advantages of Ivy compilation, but don’t miss previous functionality.
Consider the following pattern showing a decorated child class that inherits a constructor from an undecorated base class:
export class BaseDir {
constructor(@Inject(ViewContainerRef) protected vcr: ViewContainerRef) {}
}
@Directive({
selector: '[child]',
})
export class ChildDir extends BaseDir {
// constructor inherited from BaseDir
}
Angular ViewEngine already supports this pattern. Still, it was missing in Ivy's initial release: without the @directive annotation identifying the BaseDir class as a directive, the Ivy compiler didn't interpret information about its constructor parameters.
Version 9 will now ship with his feature so that it becomes consistent across all of the Angular codebase.
Angular Diagnostics Improvements
Previously, the Angular Compiler generated both native TypeScript diagnostics and its own internal API diagnostics. But TypeScript diagnostics have benefited from recent enhancements, none of which were implemented in API diagnostics.
Instead of supporting multiple formats, Angular 9 will simplify the process by converting all Angular TypeScript Compiler (ngtsc) diagnostics to the same TypeScript Diagnostics format.
Version 9 will also keep apps from running into potential binding issues by using the schema registry to check DOM bindings. In addition, consistent template diagnostics will be usedto support the generation of highly descriptive error messages.
Internationalization with Angular Ivy
Another Ivy enhancement relates to internationalization.
You can use the Angular CLI to generate most of the standard code necessary to create files for translators and to publish your app in multiple languages.
Bon! Bueno! Schön! Bravo!
For example, consider an application with this HTML title in English:
<h1>Hello world!</h1>
You can add the i18n attribute to mark “Hello world!” as translatable text ("i18n" is a shortening of "internationalization" — "i", 18 letters in between, and "n."):
<h1 i18n>Hello world!</h1>
After you have configured your app to use i18n, you can run the xi18n command to extract the localizable text into a file. You can see a snippet of a generated messages.xlffile below:
<trans-unit id="a05c3a315a6ee3e6ad4733a1f72e8d16775810ca" datatype="html">
<source>Hello World!</source>
<target/>
</trans-unit>
Then, you can copy the messages.xlf file to the messages.es.xlf file below and change it to build the app for Spanish (es) locations with the translated content:
<trans-unit id="a05c3a315a6ee3e6ad4733a1f72e8d16775810ca" datatype="html">
<source>Hello World!</source>
<target>¿hola, qué tal?</target>
</trans-unit>
In Angular 9, the i18n code has been refactored to provide a better platform for adding compile-time inlining.
Dependency Injection Changes in Angular Core
Now let's take a look at some smaller, but no less welcome, updates and improvements we'll see in Angular 9.
Angular Core has some enhancements too. For example, Angular 9 adds dependency injection support for the providedIn value:
@Injectable({
providedIn: 'platform'
})
class MyService {...}
Angular 9 extended the vocabulary for the providedIn property to also include the 'platform' and 'any' scopes.
Type-safe Changes in Angular Core
Angular 9 offers modified TestBed (the main unit test API for Angular apps) to replace the old get function with the new inject method. The get method still works, but is deprecated. TestBed.inject is the preferred option starting with Angular 9:
// This code still works, but it's deprecated:
TestBed.get(ChangeDetectorRef) // returns any
// inject() now replaces get():
TestBed.inject(ChangeDetectorRef) // returns ChangeDetectorRef
Currently, TestBed.get is not type-safe. Fixing TestBed.get would introduce a massive breaking change, so the Angular team decided to replace it with TestBed.inject.
Language Service Improvements
The Angular 9 Language Service for Visual Studio Code and WebStorm will benefit from some improvements. For example, URL definition will become more consistent. Style URLs will be checked in the same way as template URLs.
Since building is an expensive task and should not be bundled with testing scripts, Angular 9 will introduce a convenience script so that building the distribution doesn't have to happen on the repo root. Language Service integration tests should reinstall the Angular distribution every time it is built.
Diagnostics will also be improved in the Angular Language Service. For example, TypeScriptHost will be able to differentiate severity logging by log, error, and debug methods. Plus, template URLs and style URLs that do not point to actual files will now be diagnosed as such by the Language Service.
In the future, Language Service implementation can be further improved with enumerating directive properties and unifying common logic.
API Extractor Improvements
Angular depends on many software libraries that evolve separately. Angular users can miss out as potential bugs are resolved and new features are implemented in these libraries.
In response, Angular 9 will update API Extractor to the newest version. Angular uses Bazel, an open-source tool that enables building automation and software testing. Bazel references API Extractor, a tool invoked at build time by the Angular toolchain. It leverages the TypeScript compiler engine to detect the project's exported API surface, produces a contracts report, points out missing exports and inconsistent visibility, and generates API documentation.
Maybe not the most exciting update, but really it's the details like regular improvements to the Language Service and API Extractor that make a framework productive and efficient when we're coding apps.
Benchmarking Angular 8 vs. Angular 9
We promised a head-to-head match-up, and now it's time to deliver.
Angular 8 already allowed smaller and faster apps compared to version Angular 7. Since the Angular team didn't stop working on performance improvements, many of us waited anxiously to see how Angular 9 would compare, particularly with the addition of the Ivy as the default compiler.
This benchmark was run with a new application created with Angular CLI:
ng new angular-new
Then we built it with the production build option, again with Angular CLI:
ng build --prod
The benchmark was done by Google Chrome's built-in Audit functionality, using the following test settings:
- Device: Mobile
- Audits: Performance
- Throttling: Applied Slow 4G, 4x CPU Slowdown
Angular 8.2.7
A production build with Angular 8.2.7 resulted in a main.js of 246KB for ES2015 browsers. Here we can see a screenshot of the performance results:
Angular 9.0.0-next.5
A build with Angular 9.0.0-next.5 yielded a slightly small main.js file at 214KB. That's a 13 percent improvement from Angular 8.
Here are the Angular 9.0.0-next.5 benchmark results:
These results are partly a reflection of the performance improvements enabled by the Ivy renderer in Angular 9.
Update: Angular 9.0.0-rc.9
Now that we’re closer to the final Angular 9 launch, let’s take another look and see if bundle size and performance have changed.
The total ES2015 bundle size of our app is now 177KB - significantly smaller than both Angular 8 and the previous Angular 9 pre-release version we tested. Next, let’s look at performance:
Although the audit score is one point lower than before, this doesn’t represent a meaningful drop in performance.
With better performance that Angular 8 and a much smaller app bundle size, most Angular developers will want to update their apps to use Angular 9 after its final release.
The Future of Angular
With Angular 9, the community can benefit from smaller, high-performance applications, and a better developer experience. Developers also now have clear syntax and clear project structure.
What changes will be incorporated into Angular in the future?
The Angular team has indicated that there's no need for drastic API changes. Will there be more deprecations, and maybe an alternative way of creating components? An enhanced developer experience is always something to hope for. In the future, perhaps we'll be spending more time on developing components and directives and less time in trying to glue them together.
Looking for framework-agnostic UI components? GrapeCity has a complete set of JavaScript UI components, including data grids, charts, gauges, and input controls. We also offer powerful spreadsheet components, reporting controls, and enhanced presentation views. We have deep support for Angular (as well as React and Vue) and are dedicated to extending our components for use in modern JavaScript frameworks.
Supporting the Ivy Compiler
We have been working closely with the Angular team to make sure we support the new Ivy Compiler so our customers can use Angular v9. The Angular team helped us with some recommendations in our module packaging and fixed some compiler issues as well. During this process, we also migrated to use the Terser minifier for better parsing in the Ivy Compiler based on the Angular team's recommendation. Read more about how Wijmo Supports Angular 9 and the Ivy Compiler.
No comments:
Post a Comment