Angular 9, released in February 2020, brought the development community lots of long-awaited features: the default Ivy compiler, bundle and build optimizations, improved bug checking during the build, and more. The Angular development team claims the improvements in this version greatly reduce app bundle sizes and build times.
In this article, we go over the key features of Angular 9 and 9.1 and test their performance on a real-world project. We also evaluate the updates brought by Angular 10.
This Angular 9 overview will be useful for developers looking to assess the latest features and performance improvements in Angular.
Angular is a web development platform created by Google. Convenient functionality, an a robust command-line interface (CLI), support for various development tools, and frequent releases make this platform one of the most popular choices for building web applications. According to GitHub and Stack Overflow, Angular is the third most popular web development framework after React and ASP.NET MVC.
Angular 9 is one of the biggest updates to Angular in the last three years. Let’s see what’s new in the Angular 9 release.
The default Ivy compiler and runtime improvements are the most important changes in Angular 9. In previous versions, developers had to use the View Engine compiler that had a long build time and produced large bundles compared to the new compiler.
Nowadays, lots of users surf the web via smartphones, accessing vast amounts of data: high-resolution videos, streaming music, datasets, etc. Web apps need to deliver the best user experience even under the worst conditions. But heavy loads reduce web application performance. That’s why developers tend to choose frameworks that load applications and evaluate scripts fast.
The new Ivy compiler allows developers to speed up development and make it more efficient. Ivy helps developers rework the internal application structure with a focus on two things: day-to-day developer needs and bundle optimizations for the final production application. The new compiler is also supposed to significantly speed up the build process and reduce bundle sizes.
Let’s take a close look at each improvement and find out how it facilitates development.
Application performance and bundle size used to be weak spots of Angular. In version 9, they’re finally resolved. Thanks to tree shaking and reworked dependency management in the underlying architecture of the framework, you can see major performance and bundle size improvements in both small and large applications.
Tree shaking excludes large parts of unused framework code from the application bundle, helping to reduce the final size of the bundle up to 30%. This mechanism is especially effective for small applications. These apps don’t really use the majority of Angular features, so a large part of the bundle was often so-called “dead code.”
Another useful feature of Angular 9 is the optimization of component factories. The impact of this optimization directly depends on the number of components, making it especially significant for large applications with lots of them. The Angular development team claims a bundle size reduction for large applications of up to 40%.
Previous Ivy versions added almost 80% overhead compared to pure TypeScript compilation. In Angular 9, this overhead is reduced to ~50%, allowing you to build applications much faster.
Optimization and performance improvements aside, Ivy also changes the way developers work with debugging, testing, and build errors. In Angular 9, the compiler checks more error types and applies stricter checking rules than it did in the framework’s previous versions. So finding bugs no longer requires a lot of effort from developers.
Improved bug detection also helps to reduce the cost of fixing bugs and, ultimately, the project budget. Since the build is one of the earliest stages of application development, detecting and resolving an issue at this stage has a lesser influence on the project than fixing the same issue later.
The Angular 9 compiler supports two additional flags to check templates:
fullTemplateTypeCheck— tells the compiler to check ngIf, ngFor, ng-template, and other templates
strictTemplates— activates the strictest type checks for templates
By using these flags, you can detect more errors in the console. Angular 9 provides you with a clear description of each detected error and its causes. Ivy also improves the stack trace of internal errors, allowing you to jump directly to the parts of your code related to a specific error.
- access your components and directive instances
- trigger change detection
- directly call certain methods
Built-in testability and dependency injection always were features that attracted developers to Angular. But even though testing is one of the built-in concepts, test execution time was always something to complain about, especially in large applications.
The revamped implementation of the TestBed API doesn’t recompile components between tests unless a component has been manually overridden. This change significantly shortens the duration of test execution: acceptance tests are 40% to 50% faster.
Another testing improvement in Angular 9 is the test component harness — a class that allows tests to interact with components via a supported API. Now you can significantly simplify user interface tests of material components or implement your own harnesses using a component development kit.
Without using component harnesses, tests used to look like this:
In Angular 9, the same test requires much less code:
As you can see, improving the default compiler made this platform much more comfortable to work with and made the compilation process much more efficient. However, Angular 9 improvements aren’t limited to the Ivy compiler and the performance optimizations it provides. Let’s look at some new components that make developers’ lives easier.
The ninth version of Angular supports TypeScript 3.7. The key feature of TypeScript 3.7 is optional chaining, which helps TypeScript stop expressions that run into
undefined. As a result, you don’t need to write safety code like this:
With optional chaining, the same code looks like this:
Adding nullish coalescing gives us a safer option for the same expression:
You can check out all the improvements in TypeScript 3.7 in the official documentation. Note that TypeScript 3.7 doesn’t list uncalled function checks, which have a significant impact on coding. Functions are always defined and shouldn’t be checked as conditions, and uncalled function checks notifies a developer if there’s a typo in conditional operators that will make a function uncallable.
Shortly after the version 9 release, the Angular development team rolled out Angular 9.1 — a minor release containing improvements to the framework and the CLI as well as bug fixes. In particular, version 9.1 introduced an upgraded ngcc compiler, new CLI component generator options, and performance and stability improvements. Angular 9.1 also updates Typescript to version 3.8, which, in fact, doesn’t bring any major changes compared to version 3.7.
Four months after the Angular 9 release, the Angular team released version 10 of the framework. This update isn’t as large and significant as version 9, but it’s still worth a look.
The most important change in this update is the
--strict option in the CLI. It allows you to enable strict linting rules for an Angular application on bootstrap. Strict linting is aimed at simplifying development by eliminating warning signs during compilation. You can turn on strict linting with this command:
This option does the following:
- Enables strict mode in TypeScript
- Turns template type checking to
- Configures linting rules to prevent declarations of type
- Turns on features that enable more build and bundle size optimizations
The next important change is that Angular 10 doesn’t support old browser versions by default. The side effect of this decision is disabling the ES5 bundle build by default for new projects. This bundle used to significantly increase the overall application bundle size. Yet you still can add support for old versions of browsers you need by editing the .browserlslitrc file.
Also, to improve build optimization, Angular 10 makes changes in many outdated features:
ContentChildrenqueries search only direct child nodes by default
- Undecorated classes are no longer included in the Angular dependency injection system
- Unbound inputs are now set upon creation of the view
- In case of conflicts, static attributes from the HTML template override host attributes set by directives or components (previously, static host attributes overrode static template attributes)
You can check out the full list of deprecations to find out about other features.
During 2020, the Angular development team augmented their framework with many features designed to speed up development and make web apps lighter. But do they really speed up the development of real-world projects? Let’s compare the performance of Angular 9.1 and previous versions of the framework to find out.
Since Angular 10 doesn’t bring any major optimizations or upgrades to the framework, we’ll focus on testing the new features in Angular 9.1 in the real world. For this experiment, we’ll use the Tour of heroes application that’s familiar to lots of developers who have learned Angular. We used the Tour of heroes repository as a starting point since it’s written in Angular 8.2. Then we built this project with three different versions of Angular and received the following results:
Overall output size
As you can see, builds in 8.2 and 9.1 became faster, but not significantly. That’s why for continuous integration and continuous delivery (CI/CD) pipelines, where the build is executed mostly in Docker from scratch, the new version of Angular doesn’t seem to give an advantage.
In our experiment, we also didn’t achieve any size reductions. As we mentioned before, bundle optimization should be most noticeable in large projects, with less of an effect on small and medium-sized applications.
On the bright side, another important takeaway of this test is that we didn’t experience any issues with upgrading Angular dependencies to the newest versions. You can find all the instructions you need for upgrading dependencies in the update guide provided by the Angular team.
The smooth update experience provided with ng CLI simplifies updates significantly, whether you need to move to Angular 9.1 or 10. Note that version 10 also includes a list of not-so-obvious breaking changes that may cause issues on big projects. We highly recommend getting familiar with these changes before considering updating to the tenth version of the framework. Or you can check out the newly-released Angular 11.
During our experiments, we didn’t experience any of the advertised optimizations and performance improvements in Angular versions 9 and 10. However, these versions of the framework provide lots of benefits and useful tools:
- AOT is now finally available for build development
- The TestBed API speeds up your tests by avoiding recompilation between executions
- Implementing tests is simpler thanks to component harnesses
- TypeScript updates allow you to use new TypeScript features
If you’re looking for a development team with expert knowledge of many web app development frameworks including Angular, feel free to contact us!