DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Angular Best Practices For Developing Efficient and Reliable Web Applications
  • React, Angular, and Vue.js: What’s the Technical Difference?
  • Step-by-Step Guide: Application Using NestJs and Angular
  • Create a Beautiful Login Form With Angular Material

Trending

  • Unit Testing Large Codebases: Principles, Practices, and C++ Examples
  • Integrating Model Context Protocol (MCP) With Microsoft Copilot Studio AI Agents
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • AI’s Role in Everyday Development
  1. DZone
  2. Coding
  3. JavaScript
  4. How To Improve the Performance of Angular Apps

How To Improve the Performance of Angular Apps

How do you improve the performance of Angular apps? Read this blog post to find the ways – from reducing unused JavaScript and CSS to Angular lazy loading.

By 
Konstantin Dinev user avatar
Konstantin Dinev
·
Sep. 08, 23 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
4.2K Views

Join the DZone community and get the full member experience.

Join For Free

Angular has become a very popular and widely adopted framework for developing modern web applications. This technology is both very powerful and feature-rich. Everything that you need as a web developer comes out of the box, and Angular allows for easily configuring, maintaining, and expanding any application built on top of the framework.  

And by now, you’ve probably already put together one or more Angular applications, but are they optimal?  

In Part 2 of my Software Performance series, then, I will talk about Angular optimization, demonstrating how to improve the performance of an Angular application using an Angular example app that I built. I will use Chrome Dev Tools to derive an initial lighthouse score to determine where the application initially stands. Let’s take a look at what can be improved and how. 

How To Improve the Performance of Angular Applications 

For this article, I will use a sample Angular application that I’ve put together. At the time of writing this article, the application uses the following features and libraries: 

  • Angular 16
  • Ignite UI for Angular 16
  • RxJS 7
  • PWA (Angular service worker)
  • Server-side rendering (express server)
  • Angular localization

Angular Build

Everything seems to be running just fine when I’m running the application in a development environment, but the initial lighthouse score is not very high:

 Lighthouse score with development environment run

When I look at the suggestions for improving the lower-scoring sections, I see where the issues are coming from. The first big issue is the size of the resources (JavaScript, styles, static resources) that are transferred to the client. 

 Opportunities for improving performance of the Angular app

This issue is resolved easily by running a production build of my Angular application rather than a development one. Always build with production configuration prior to deployment. This will resolve the warning to reduce the size of JavaScript and CSS. Let’s take a look at the angular.json file at the root of our Angular repository to see how the production build differs: 

JavaScript
"configurations": {
 "production": {
 "budgets": [
 {
 "type": "initial",
 "maximumWarning": "2mb",
 "maximumError": "5mb"
 },
 {
 "type": "anyComponentStyle",
 "maximumWarning": "10kb"
 }
 ],
 "fileReplacements": [
 {
 "replace": "projects...Code


There’s quite a lot of configuration here. However, the most important one, in this case, is the "optimization": true one. Once I run the application with a production configuration, the difference in score is significant in terms of load-time performance: 

 Lighthouse score with production build in dev environment

If I look at the opportunities list again, the number of suggestions is much lower. The biggest opportunities listed at about text compression are unused JavaScript and caching of static resources:

 Remaining opportunities for performance improvements

Angular Pre-Rendering and Server-Side Rendering 

Angular is a Single Page Application (SPA) framework. By default, the lifecycle of the app is such that upon a request from a client, the server that hosts the application serves down an HTML file that includes all the necessary script and style references. However, it is empty of body content. Once the scripts and styles are requested and served, the application is bootstrapped and populated with content based on the JavaScript logic for the given application. Angular provides two mechanisms to improve this lifecycle by serving actual content in the initial HTML document. To do this, the JavaScript logic of the application needs to be executed prior to serving the document. The ways to do it: 

  • Either at build time (pre-rendering) - for pages with mostly static content. 
  • Or at run time on the server (server-side rendering) - for pages with more dynamic content that need to deliver up-to-date content on every request. 

I have enabled server-side rendering for the Angular example app, and I’m using the express engine to enable text compression and static resource caching. This is done by adding the following to my express server logic:

JavaScript
export const app = (lang: string) => {
 // server scaffolded by [ng add @nguniversal/express-engine]
...
 // enable compression [npm install compression]
 const compression = require('compression');
 server.use(compression());
...
 // Serve static...Code


I will serve the app with server-side rendering and run the lighthouse test again. The initial load improved even further, bringing the first contentful paint to under a second, while the speed index is reduced to 1.2 seconds.

 Lighthouse score with Angular server-side rendering

The leftover opportunities for Angular optimization are to reduce unused JavaScript and CSS.


To deal with these, I will have to do some application refactoring.

Angular Lazy-Loading 

In order to reduce the unused JavaScript, the best approach would be to create lazy-loaded routes. This will tell the Angular framework which components are not needed in the top-level module and will split the JavaScript into modules, the logic for which is loaded only when the requested route is loaded. 

The Angular example app that I’m using for this blog utilizes larger components, like the igx-grid, which are not part of the home route. I’m separating the routes using this component into a separate module. This way, I’m going to have that component loaded only after the routes using the component are loaded. After separating the modules, the routes look like this:

JavaScript
export const routes: Routes = [
 { path: '', component: HomeComponent },
 { path: 'register', component: RegistrationComponent },
 { path: 'unauthorized', redirectTo: 'unauthorized/', pathMatch: 'full' },
 { path: 'unauthorized/:message', component...Code


The team.module is the one loading the grid I’m using, so the code for it looks like this:

JavaScript
@NgModule({
 imports: [
 CommonModule,
 FormsModule,
 // ...
 IgxGridModule,
 // ...
 TeamComponent,
 // ...
 ]
})
export class TeamModule { }Code


Looking at the build, this is the result of the initial splitting:

 Separating the Angular app into lazy-loaded modules

Another thing that needs to be done to improve the performance of the Angular application is to limit the size of the CSS to the styles that are used. I’m using Ignite UI for Angular as my UI library and there’s a great how-to article on customizing and optimizing the component themes. 

Optimizing Images 

Another aspect of the Angular optimization that should be done is optimizing the images. Lighthouse check will tell you if you’re using suboptimal images by type or size. Make sure the images you load are not larger than the containers they go in and they are with optimal encoding. I now use .webp format for images. It reduces the quality a little, but still, the application does not require the highest fidelity images. 

Images cause layout shifts after they are loaded. Hence, it’s a good idea to set width and height attributes on the images so the browser knows the dimensions before loading the images. If you’re missing aspect-ratio settings (width and height) on the images, Lighthouse will warn you. This will reduce or completely eliminate the layout shifts. 

NgOptimizedImage to Enforce Image Best Practices 

Angular exposes a directive that enforces image best practices and optimizes image loading for you. It’s called NgOptimizedImage and it is rather easy to use. All you need to do is import CommonModule if you’re still in an NgModule based Angular application or import NgOptimizedImage in the component where you want to use it. Then, instead of using src to set the image source attribute, you use ngSrc instead.

JavaScript
 Code


Finally, you can further specify the loading priority for each image and tell the app to lazy-load every non-critical image. If I remove the width and height attributes, then what I get running the app is:

 NgOptimizedImage enforcing best practices

And that’s it. 

Wrap Up… 

Improving the performance of Angular applications may require continuous monitoring, optimization, and best practices to ensure the app performs efficiently and reliably under various conditions. But in the end, this is how you deliver the ultimate UX, attract and retain users, maintain competitiveness, and achieve business success.

CSS JavaScript UI AngularJS application Production (computer science)

Published at DZone with permission of Konstantin Dinev. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Angular Best Practices For Developing Efficient and Reliable Web Applications
  • React, Angular, and Vue.js: What’s the Technical Difference?
  • Step-by-Step Guide: Application Using NestJs and Angular
  • Create a Beautiful Login Form With Angular Material

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!