DEV Community

Cover image for Optimizing Angular Applications
Nichola Alkhouri for This is Angular

Posted on • Updated on

Optimizing Angular Applications

In this article you can find some selectable tips that help you optimize you angular application, I hope you benefit from it in your projects. Lets start.

Critical CSS Inlining:

This is a new and cool feature. During the build process, Angular will parse the CSS selectors and try to find a match against the rendered page. Accordingly Angular will decide if that style is part of the Critical Path, and will inline those styles in the HTML. Enabling this feature will improving the First Contentful Paint metric of your page.

You can enable the critical css inlining by adjusting the optimization browser builder option in angular.json file:

"optimization": { 
  "styles": {
    "minify": true,
    "inlineCritical": true // enable critical css inlining
  }
}

If you are using Angular Universal to SSR your application, and want to enable Critical CSS Inlining, you need to enable it in server.ts file

  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
    inlineCriticalCss: true
  }));

Font Inlining

This is another way to improve the First Contentful Paint. You can enable this optimization option If you are using a google font, angular will then inline the google font in the index.html file. This will save you one extra request that the browser needs to do in order to get and render the font.

You can enable the font inlining also from the optimization browser builder option in angular.json file:

"optimization": { 
  "fonts": {
    "inline": true,// enable font inlining
  }
}

You can learn more about the Critical Css Inlining and Font Inlining here https://angular.io/guide/workspace-config#styles-optimization-options.


Use OnPush Change Detection Strategy

This strategy prevents angular from running change detection on the entire component subtree, which leads to faster execution. You can enable OnPush change detection in the Component configuration metadata by changing the changeDetection property as the following:

@Component({
    selector: 'my-company',
    templateUrl: './my-company.component.html',
    styleUrls: ['./my-company.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})

This will deactivate the automatic change detection for this component and its child directives, but keep the possibility to the change detection to be explicitly invoked. The only three cases where angular run change detection on your component in this case are :

  1. One of the component @output references has been changed.
  2. Any Dom event from within the component or one of its child directives.
  3. Explicitly triggering change detection.

Here you find two in detail article about OnPush change detection:

https://netbasal.com/a-comprehensive-guide-to-angular-onpush-change-detection-strategy-5bac493074a4

https://blog.angular-university.io/onpush-change-detection-how-it-works/


Server Side Rendering with Angular Universal

In a previous article I used Angular Universal to server-side render a sample web application in order to improve the user experience and boost Core Web Vitals scores.

By default, Angular applications are rendered client-side. In other words, the browser loads all the application javascript files, bootstrap the application, made the necessary API calls to get the data to be displayed, and then render the final page. While Angular Universal will execute the application on the server-side, generate a static HTML which will be passed to the client to directly render it to the user. After that, the browser will load the javascript files and re-hydrate the application on the client-side. As a result of this, the application will be rendered much faster, and the user will be able to see the rendered page earlier.

You can find a full details on how to enable and use Angular Universal here https://angular.io/guide/universal


Use Lazy Loading

Modules Lazy Loading

By default, all your Angular code is shipped to the client in one bundle. This bundle could grow in size as you keep adding new features to your application. Luckily Angular supports the ability to lazy loading part of your application. This will improve the initial loading of your application, and so the Largest Contentful Paint (LCP). In meanwhile Angular supports lazy loading through routing. Which means you can lazy load parts of your application as long as it has a separate routing.

You can find more in details about how to lazy load your angular modules in the official Angular documentation https://angular.io/guide/lazy-loading-ngmodules

Components Lazy Loading

With the new Ivy renderer, it is now possible to lazy load Angular Components, which is a great feature. However, it requires some exatra manual work to do it, especially when your component contains some child directives or child components.

Here you can find a great article on how Components Lazy Loading works https://johnpapa.net/angular-9-lazy-loading-components/


Use the available tools

Finally, there are a bunch of tools you can use to measure the performance of your application, which is the first step in the optimization process. Many of these tool also provide you with suggestions on how to fix potential issues in your applications. Probably the most important of these tools are:

  • Lighthouse: an open-source project, shipped with chrome dev tools, with the aim to improve the quality of web pages.
  • PageSpeed Insights: an online tool to generate a performance report of a page on both Desktop and Mobile devices, and provide you with a wide range of suggestions on how to improve and fix the existing issues.

Top comments (2)

Collapse
 
timsar2 profile image
timsar2

angular.json has "optimization": true
should I change it as object?

Collapse
 
nicholaalkhouri profile image
Nichola Alkhouri

Yes, "optimization" can be either a Boolean or an Object, find more about it in the official documentation here: angular.io/guide/workspace-config#...