Clever white space handling for better performance in Angular 5+ and 4.4

This post is part of my Angular Performance Tuning article series. If you looking for ways to make your Angular application faster, you might find the other articles in this series useful too.

Update: This optimization technique has now been merged into Version 4.4.0-rc.0 too.

Although tuning an application's performance can be difficult, sometimes all we need to do is laying back and waiting for the next version of the used framework. This especially holds true for Angular as the Core Team is working constantly on improving things under the hoods. A good example for this is the conciser code the Angular Compiler emits beginning with Version 4 or the Angular Bundle Optimizer that transforms code to make it more treeshakable.

Another of these optimization techniques landed with 5.0.0-beta.4 about two weeks ago. It allows the compiler to remove unneeded (consecutive) white spaces from text nodes and to remove even whole text nodes that only contain white space characters. This leads to less code emitted by the AOT compiler and therefore to smaller bundle sizes as well as faster start up times.

In this post I'm describing how to use it, which performance gains I measured when applying to an example application as well as how this approach works under the covers. The example application I've used for this can be found in my GitHub repository.

Removing white spaces

While removing white spaces from HTML is most of the time a safe operation (at least when respecting some rules outlined below), it can also destroy your layout. Because of this, you have to opt-in for it. For instance, you could to this on component level by setting the new property preserveWhitespaces to false:

@Component({
  selector: 'app-passenger-search',
  templateUrl: './passenger-search.component.html',
  styleUrls: ['./passenger-search.component.css'],
  preserveWhitespaces: false
})
export class PassengerSearchComponent  {
}

Instead of this, you can also set this property on application level by passing the new preserveWhitespaces command line option when calling the Angular Compiler ngc. At the time of writing, the Angular CLI did not support this option but this seems to be just a matter of time.

In addition to this, you can protect a section within a template by adding the attribute ngPreserveWhitespaces to a tag. If you want to spot a space that isn't allowed to be removed, you can use the pseudo-entity &ngsp;, which is converted to a space in the emitted code. Don't confuse this with the well known entity.

Results for example application

When I applied this optimization technique to my example application, I got the following results:

  • ~ 8% reduction in size for the javascript bundle
  • ~ 4% reduction in size for the gzipped javascript bundle
  • ~ 9% faster application startup time

As this shows, this approach allows for an appreciable performance gain. This gain we get after "just" removing white spaces is higher than you might have expected. The next section shows how this is possible.

Under the hoods

To understand why such a high performance gain is possible by "just" removing white spaces, let's look at a simple template:

<h1>
  Search for Passengers 
</h1>
<p>
  Lorem ipsum dolor sit amet.
</p>

When we compile this template, the AOT compiler transforms it to JavaScript code:

function View_PassengerSearchComponent_0(_l) {
  return __WEBPACK_IMPORTED_MODULE_1__angular_core__["_37" /* ɵvid */](
      0,
      [
        (_l()(), __WEBPACK_IMPORTED_MODULE_1__angular_core__["_15" /* ɵeld */](
                     0, null, null, 1, 'h1', [], null, null, null, null, null)),
        (_l()(), __WEBPACK_IMPORTED_MODULE_1__angular_core__["_35" /* ɵted */](
                     null, [ '\n  Search for Passenger \n' ])),
        (_l()(), __WEBPACK_IMPORTED_MODULE_1__angular_core__["_35" /* ɵted */](
                     null, [ '\n' ])),
        (_l()(), __WEBPACK_IMPORTED_MODULE_1__angular_core__["_15" /* ɵeld */](
                     0, null, null, 1, 'p', [], null, null, null, null, null)),
        (_l()(), __WEBPACK_IMPORTED_MODULE_1__angular_core__["_35" /* ɵted */](
                     null, [ '\n  Lorem ipsum dolor sit amet.\n' ]))
      ],
      null, null);
}

As you can see, this code contains a function call for each dom node we need. For instance, there is a function call for the h1 tag as well one for the p tag. In addition to that, there are function calls for text-nodes. When analyzing this, we find characters as well as even a text node that aren't displayed in the browser due to the way HTML works. Examples are consecutive white spaces as well as empty text nodes like the one between the closing h1 tag and the opening p tag.

When using the discussed technique, the compiler removes these whites spaces or these text nodes. The following image shows a diff between the emitted code above and the code that is created after activating white-space-removal:

diff between version with and w/o whitespaces

This shows that a whole function call as well as some consecutive white space characters are removed. When we just count the removed lines for the sake of simplicity we see they make up about 10 % of all lines. This explains the reduction in bundle size we've faced. Of course, a reduction in function calls means that the Browser can download the bundles faster as well as Angular has less to do when starting the application. Both leads to the improvement of start up performance mentioned above.

 

 
Sie wollen mehr zum Thema Clever white space handling for better performance in Angular 5+ and 4.4 wissen? Hier können Sie eine Anfrage für eine unverbindliche Schulung ode Beratung bzw. einen Workshop erstellen.
 
Unverbindliche Anfrage
 
 

Schulung und Beratung

Angular

Datenbindung, Formulare, Validierung, Routing, HTTP, Komponenten, ...

Details

Angular: Advanced

Erweiterte Aspekte von Angular

Details

Reaktive Architekturen mit Angular und Redux

Dieses interaktive Seminar vermittelt, wie Sie reaktive Anwendungen mit Angular entwickeln können.

Details

Migration von AngularJS 1.x auf Angular (2+)

Bestehende Projekte auf Angular 2 migrieren, ngUpgrade, ...

Details

Angular Review

Feedback und klärung offener Fragen, weiterführende Themen

Details

Angular Workshop

Start ohne Umwege

Details

Weitere Schulungen ...