This content originally appeared on Bits and Pieces - Medium and was authored by Kamil Konopka
A guide on optimizing the performance of Angular apps using the RxJS library along with other Angular features.
Nowadays, performance optimization tends to be an extremely popular topic, especially among users and their business representatives. As a user, I want to be able to navigate, add to my shopping cart, checkout or browse without any delay! I want to access the content I am looking for almost instantly. Users do not want to wait or interact with slow-working/buggy applications. And it’s their right to demand it!
Our job is to make it happen. We are responsible for our end product performance (user happiness!), but do we really know how to achieve this ultimate goal with the Angular application?
Throughout my entire career, I’ve been involved in different projects in different development stages (sometimes I’ve joined late to the party!) and I’ve seen lots of things within the code that literally blew my mind. There were times when I thought: Nothing can surprise me now. But I was wrong! I still keep finding things and implementations which could cover the entire “Programming Anti-Patterns” book.
Some of these impact application performance directly, so hard, I was surprised how the project could get that far with business approval. The root cause of the situation in most cases is a lack of technical knowledge on the “clients” side. We can dress performance issues in a “very complex logic, very complex system” uniform and still sell it to the client. This will work, but not for long. Trust me!
💡 Before starting, check out some Angular dev tools mentioned in this article that you could consider using. One such tool is Bit. With Bit you can extract reusable Angular components from your codebase and reuse them across multiple projects, reducing code duplication and minimizing boilerplates.
Learn more here:
We can make our life easier and save ourselves a lot of trouble, by thinking about the performance of our app instantly (at every project stage). There are different flavours of performance perspectives we can possibly think of:
- application loading time — one of the key factors here might be device type/internet connection speed etc.
- interaction between different application features — how fast search functionality works / typeahead options are being fetched / how quickly I can add the same product to the cart and so on.
In the case of application loading time, we need to take into consideration:
- media(image/video) optimization — proper optimized format like webp, but also can be improved in Angular by using [ngSrc] attribute.
- application bundle size — gzip compression could be used to significantly reduce sizing, also lazy loading for modules or standalone components can be introduced, so not everything gets loaded at the start. Specifically, standalone components are making a huge impact on size!
- API communication between application layers — atomized into separate, reusable entities.
In case of interaction, let us dive deeper into some programming techniques that might have impacted our application, which can be optimized.
Remember to always unsubscribe when component will get destroyed! This has huge impact on the application performance!
One of the key foundations of Angular 2+ (up to 16 at a time of writing this article) is the Rxjs library (Reactive Extensions Library for JavaScript). Where the key concept is based on reactivity! And this is all we need — a truly reactive programming approach within our application. It is important to highlight, that the Rxjs library itself might not be enough, we need to combine it with Angular features in order to achieve our goal.
The aim with reactive programming approach is to react on actual user interaction, rather then constantly checking if something has been changed! We should provide mechanisms to trigger change only as response of the actual interaction! If there’s no input, nothing should get triggered in our code!
Sounds obvious right? But do you know what you should avoid using in your code to comply?
- You should avoid using getters in your components. Getter is an opposition of reactivity — it gets triggered just like ngDoCheck lifecycle-hook. We do not want that! We want to control our data flow/change emissions. With getters, we do not have control at all.
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
standalone: true,
})
export class NavigationComponent {
get formValues(): string {
return this.form.value;
}
form: FormGroup = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
});
}
We should listen to valueChanges of the form instead! This way, we will get the most recent values, only when they’ve been changed! This is not only applicable to forms but to every use case. Angular already has its own mechanisms in place to handle change, like ngOnChanges lifecycle-hooks, which get triggered when values passed via inputs have been changed.
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
standalone: true,
})
export class NavigationComponent implements OnInit {
form: FormGroup = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
});
ngOnInit(): void {
this.form.valueChanges
.pipe(
// remember to unsubscribe!!!
)
.subscribe((formValues) => {
/* side note: formValues will contain only attributes from enabled controls
need data for disabled controls too? use this.form.getRawValue() */
})
}
}
- Using ChangeDetectionStrategy.OnPush with proper containers components approach
- Avoid using [(ngModel)] (banana in the box ) at all cost, as you will not be able to control the change
- update your data in an immutable way — do not mutate! Otherwise, your changes will not be detected by the change detection mechanism. In order to make the change detection mechanism work properly, the reference to your data needs to change!
- atomize your data! — to make it easier to manage.
- if you do not have an idea, what is the best practice to implement the feature, read the documentation!
These couple of rules will have a significant impact on the entire application's performance. Just give it a try for one feature implementation and you’ll immediately feel the difference!
Build Angular Apps with reusable components, just like Lego
Bit’s open-source tool help 250,000+ devs to build apps with components.
Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.
Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:
→ Micro-Frontends
→ Design System
→ Code-Sharing and reuse
→ Monorepo
Learn more:
- Introducing Angular Component Development Environment
- 10 Useful Angular Features You’ve Probably Never Used
- Top 8 Tools for Angular Development in 2023
- Getting Started with a New Angular Project in 2023
- How We Build Micro Frontends
- How to Share Angular Components Between Projects and Apps
- How we Build a Component Design System
- Creating a Developer Website with Bit components
How to Optimize the Performance of Angular Apps was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Kamil Konopka
Kamil Konopka | Sciencx (2023-05-23T12:46:41+00:00) How to Optimize the Performance of Angular Apps. Retrieved from https://www.scien.cx/2023/05/23/how-to-optimize-the-performance-of-angular-apps/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.