How to Fix Memory Leaks _ Better Programming
How to Fix Memory Leaks _ Better Programming
Member-only story
WEB PERFORMANCE
Performance timeline record: before and after memory leak fix (animation created by author)
If you prefer to watch, you can check my video course on Udemy: How to Identify,
Diagnose, and Fix Memory Leaks in Web Apps.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 1/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
In the last year, my team assigned me a task about fixing a performance problem in
one of our Angular apps. At that moment, I was scared. I felt like I was being
punished by that task.
A big part of the target app was written by me, but I didn’t know what I should do to
fix it. The app was running smoothly at the beginning, but after adding new features
— like inline edit for an Angular material table — it was running slower and slower
and took a long time to load that the end-user was totally unhappy with it.
Armed with some knowledge learned from Addy Osmani’s tutorials, I started my
mission.
In the beginning, I was struggling. The performance was so bad that even
Lighthouse could not start running with it. I got an error with Lighthouse caused by
the very long First Contentful Paint (FCP) and Time To Interactive (TTI), but after a
few days, my enthusiasm increased as I’d seen an improvement in the result of
Lighthouse Audit and Chrome DevTools performance analysis.
Yes, I did it. I even got very positive, encouraging feedback from the team and
stakeholders after presenting what I did to achieve this outcome from the
performance-tuning journey.
A few weeks later, a second Angular app, that my team was taking care of, started
suffering from a similar problem but with different symptoms.
The end-users were not frustrated about the load time, but after a long session of
working with the application, they realized it became slower, sluggish, and appeared
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 2/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
to pause frequently. This time, I was not scared, but I was curious about the reason
causing the problem.
After some investigation, it turned out that the culprit was a memory leak.
Talk is cheap. Let’s create some code and see how we can produce a web app
suffering from memory leaks that damage the performance and push the users to
hate it. Here is what our sample application for today will look like:
Table of Contents
Project Setup
Code
Time for Heap Snapshot
New Feature Request
Performance Timeline Record
Identify JS Heap Memory Leaks
We’ve Got a Leak — How Do We Fix It?
∘ Action 1: unsubscribing
∘ Action 2: onlySelf & emitEvent
∘ Have we fixed it?
∘ Action 3: OnPush ChangeDetection
∘ Action 4: Angular pipe & minimize subscriptions
What’s the Difference?
Conclusion
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 3/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Project Setup
You know the drill. Fire up your terminal, run the command ng new , and provide
the name apngular-memory-leaks to create the application:
ng new angular-memory-leaks
cd angular-memory-leaks
The ng new command prompts you for information about features to include in the
initial app. You can accept the defaults by pressing the Enter or Return key.
Code
Alright, time for the good stuff. We have to follow the next steps.
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
Update app.module.ts :
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 4/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
1 @NgModule({
2 declarations: [ AppComponent, TodoListComponent, TodoDialog ],
3 imports: [
4 BrowserModule,
5 BrowserAnimationsModule,
6 ReactiveFormsModule,
7 RouterModule.forRoot([{path: '', component: TodoListComponent}]),
8 MatListModule,
9 MatButtonModule,
10 MatCardModule,
11 MatDialogModule,
12 MatFormFieldModule,
13 MatTooltipModule,
14 FlexModule,
15 MatInputModule,
16 MatSelectModule
17 ],
18 providers: [],
19 bootstrap: [AppComponent]
20 })
21 export class AppModule {}
1 <div class="container">
2 <router-outlet></router-outlet>
3 </div>
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 5/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
1 <div class="todo-list">
2 <div fxLayout="row wrap" fxLayoutGap="10px">
3
4 <mat-card class="todo-card" *ngFor="let todo of todoList" fxFlex [class.mat-elevati
5 <mat-card-header>
6 <div mat-card-avatar class="example-header-image"></div>
7 <mat-card-title>{{todo.id}} - {{todo.name}}</mat-card-title>
8 <mat-card-subtitle>Type: {{todo.type}}</mat-card-subtitle>
9 </mat-card-header>
10 <mat-card-content>
11 <p>{{todo.description}}</p>
12 </mat-card-content>
13 <mat-card-actions>
14 <div fxLayoutAlign="space-between">
15 <div *ngIf="!todo.dependencies"></div>
16 <div *ngIf="todo.dependencies" class="dependencies" fxLayout="row" fxLayoutGa
17 <i class="material-icons">all_inclusive</i>
18 <div>{{todo.dependencies.name}}</div>
19 </div>
20 <div>
21 <button mat-icon-button color="primary" (click)="updateTodo(todo)" matToolt
22 <i class="material-icons">edit</i>
23 </button>
24 <button mat-icon-button color="primary" (click)="deleteTodo(todo.id)" matTo
25 <i class="material-icons">delete_outline</i>
26 </button>
27 </div>
28 </div>
29 </mat-card-actions>
30 </mat-card>
31 </div>
32 <div fxLayout="row" fxLayoutAlign="end center">
33 <button mat-icon-button color="primary" (click)="createTodo()" matTooltip="Add TODO
34 <i class="material-icons">add_circle</i>
35 </button>
36 </div>
37 </div>
todo-list.component.css:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 6/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo-list.component.css
todo-list.component.ts:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 7/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo-list.component.ts
todo.dialog.html:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 8/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo.dialog.html
todo.dialog.ts:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 9/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo.dialog.ts
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 10/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
This is the result after running ng serve and call localhost:4200 with the browser:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 11/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
1. Open the Memory panel on DevTools after reloading your page (F5).
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 12/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
4. Play with your web app: Create eight new todo cards with the todo dialog (click on
the plus “+” button).
5. Then click on the “Take heap snapshot” icon to take a second one. The second
recorded snapshot will have a bigger size than the first one: 8.4 Mb instead of 5.5
Mb.
6. Click on Summary, then select Comparison to see the difference. Under column
“# New,” there are the newly allocated objects in the second snapshot (new arrays,
closures, Event Emitters, Subjects, …). Under column “# Deleted,” there are the
deleted objects.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 13/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
a todo of type “Writing” may depend on the three todo’s types: “Writing,”
“Reading,” or “Coding.”
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 14/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo.dialog.ts
todo.dialog.html :
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 15/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo.dialog.html
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 16/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo-list.component.ts
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 17/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo.service.ts
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 18/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
That’s pretty nifty. It’s time for some truth now. You need to repeat the previous
steps 1 to 6 to compare two new heap snapshots for the current status (an initial one
and a second one after the scenario of creating a list of many todos). The outcome
will be similar to the following:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 19/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
As you can see, the required heap size is increased by 3 MB in the second snapshot.
Many new objects, listeners, arrays, DOMs are created, but none or few of them are
deleted.
After you click on the Start button and before stopping the record, you need to play
with the application: Open the todo dialog multiple times, create new todos, add
new forms to the dialog, delete some of them with and without save, and update
some todos. Stop the record and wait until you can see the result:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 20/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Chrome and DevTools offer us the possibility of finding memory issues that affect
page performance, including memory leaks, memory bloat, and frequent garbage
collections. In the above record, the memory usage is broken down by:
GPU memory
We notice the JS heap ends higher than it began. In the real world, if you see this
pattern of increasing (JS heap size, node size, listeners size), it might mean a
memory leak. A memory leak occurs when an application fails to get rid of unused
resources and the user realizes that at some point, the application is slower,
sluggish, and will probably pause frequently, which is a symptom of potential
garbage collection issues.
5. Perform the action that you suspect is causing the memory leak.
6. Then press the “Stop recording” button (red circle) when you’re done.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 21/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Every blue vertical line is an allocation of memory for some JS objects. You can
select a line with your mouse to see more details about it.
Detached DOM tree: A DOM node could be garbage-collected when there are no
global references to it. A node is said to be detached when it’s removed from the
DOM tree but some JavaScript still references it. Such a case could be identified
by comparing two Heap snapshots and then scrolling down to elements prefixed
by Detached under the Constructor column.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 22/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
A visualization of the mark & sweep garbage collection algorithm in action (Source)
follows:
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 23/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Before removing the listener to FormGroup valueChanges , you may have noticed that
after each change of the value in the Type drop-down, there were two log messages
displayed on the browser’s console: one from console.log('form value changed') and
the other one from console.log('type changed') because triggering the field event
listener was propagated to the parent DOM event listener.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 24/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Whenever an unneeded todo form is deleted (with delete icon), you have to
remember to unsubscribe from its listeners:
I don’t think so. This improvement was no silver bullet. There’s a bit more slapped
onto these memory leaks. So, let’s continue our optimization mission.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 25/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Image source: “Performance Tuning: measure, optimize and monitor” by Addy Osmani
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 26/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Please remember that an impure pipe is called often, as often as every keystroke or
mouse move, and that an expensive, long-running pipe could destroy the user
experience.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 27/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 28/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
filter-per-type.pipe.ts
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 29/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 30/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
todo-dialog-data.model.ts
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 31/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
At the end of the scenario, JS Heap size in the performance timeline record was
~9 MB instead of ~10 MB (hover your mouse on the graph to see it).
The number of documents was two instead of seven in our first performance
record.
The JS Heap in the second snapshot was increased by 0,8 MB — after creating
nine new todos — instead of 3 MB as at the beginning of our tutorial.
The complete Angular 9 todo application is available under this GitHub repository.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 32/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Final Thought
Building large applications entails writing lots of code, complex pages, long lists,
and many components and modules. Angular is a framework that does a great job of
memory management. Nonetheless, some scenarios led to mistakes, resulting in
memory leaks and, as a consequence, a crippled user experience. We won’t know
that possibly we caused this problem until it shows up in production.
Users reload pages less and less often. They lose focus on the tasks they are
performing when performance delays are beyond one second. Beyond 10 seconds,
users are frustrated and are likely to abandon tasks. They may or may not come
back later. That’s why keeping performance optimal for long-lived sessions is
essential.
Debugging memory leaks issues can be a daunting task, and avoiding them requires
awareness about the issue and constant vigilance.
You can check my video course on Udemy: How to Identify, Diagnose, and Fix Memory
Leaks in Web Apps.
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 33/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Follow
Google Developer Expert in Angular, WTM Ambassador, a seasoned software engineer, Content Creator |
YouTube: https://www.youtube.com/@tekforge
219
14.8K 273
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 35/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
1.8K 17
344 4
19
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 37/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
49 2
Lists
AI Regulation
6 stories · 401 saves
ChatGPT prompts
47 stories · 1373 saves
Growth Marketing
11 stories · 93 saves
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 38/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
165 2
osinpaul
Developing web applications using Angular provides developers with a powerful toolkit for
creating complex and interactive applications…
76 1
4.8K 49
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 40/41
05/04/2024, 22:57 How to Fix Memory Leaks | Better Programming
Priti Jha
21
https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658 41/41