Skip to content

Commit fe4808c

Browse files
author
thomas
committed
feat(challenge35): memoization performance
1 parent 48c3578 commit fe4808c

File tree

13 files changed

+166
-118
lines changed

13 files changed

+166
-118
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
11
# Contributing
22

3-
> Thank you for considering contributing to this project. Your help is very much appreciated!
4-
5-
When contributing, it's better to first explain the challenge/exercice you are thinking about in the issue tab.
6-
7-
## Getting started
8-
9-
Please follow those step in order to succesfully make your contribution to this repository.
10-
11-
1. Fork the project
12-
2. Install **Nx Console**, this will help you work with this repository
13-
3. Run `npm ci` to install all dependencies
14-
4. Generate a new app with Nx Console > Right Click on apps folder > `Nx Generate Application`
15-
5. Copy/Paste **example.README.md** and fill it up.
16-
6. Link the main **README** with your new challenge
17-
7. Few days later, create a PR with your answer.
18-
8. Optional: write a blog post explaining your Challenge and the solution you came up with.
19-
20-
## Pull Request Process
21-
22-
1. We follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)
23-
in our commit messages, i.e. `feat(core): improve typing`
24-
2. When you are ready, create Pull Request of your fork into original repository with the title starting with **NEW CHALLENGE**
3+
Learn how to contribute [here](https://angular-challenges.vercel.app/guides/contribute/)

apps/performance/memoized/README.md

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,13 @@
1-
<h1>memoized function</h1>
1+
# Memoization
22

33
> Author: Thomas Laforge
44
5-
<!-- TODO: add Information/Statement/Rules/Constraint/Steps -->
5+
### Run Application
66

7-
## Information
7+
```bash
8+
npx nx serve performance-memoized
9+
```
810

9-
## Statement
11+
### Documentation and Instruction
1012

11-
### Step 1
12-
13-
### Step 2
14-
15-
### Constraints:
16-
17-
### Submitting your work
18-
19-
1. Fork the project
20-
2. clone it
21-
3. npm ci
22-
4. `npx nx serve memoized`
23-
5. _...work on it_
24-
6. Commit your work
25-
7. Submit a PR with a title beginning with **Answer:35** that I will review and other dev can review.
26-
27-
<a href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A35+label%3Aanswer"><img src="https://img.shields.io/badge/-Solutions-green" alt="memoized"/></a>
28-
<a href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A35+label%3A"answer+author"'><img src="https://img.shields.io/badge/-Author solution-important" alt="memoized solution author"/></a>
29-
30-
<!-- <a href="{Blog post url}" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/-Blog post explanation-blue" alt="memoized blog article"/></a> -->
31-
32-
_You can ask any question on_ <a href="https://twitter.com/laforge_toma" target="_blank" rel="noopener noreferrer"><img src="./../../logo/twitter.svg" height=20px alt="twitter"/></a>
13+
Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular-performance/35-memoize/).
Loading

docs/src/content/docs/challenges/angular-performance/12-scroll-cd.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,36 @@ sidebar:
55
order: 12
66
---
77

8-
:::note
9-
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
10-
:::
11-
128
<div class="chip">Challenge #12</div>
139

1410
## Information
1511

16-
In this challenge, you will need to optimize the change detection cycles run by Angular.
12+
In Angular, there is a library called <b>Zone.js</b> that performs a lot of magic to simplify a developer's life. Zone.js monkey patches all DOM events so that it will recheck and rerender the view when something has changed inside the application. The developer doesn't have to manually trigger change detection.
13+
14+
However, sometimes Zone.js triggers a lot more change detection than needed. For example, when you are listening to a scroll event, each scroll event will dispatch a new change detection cycle.
1715

18-
Zone.js triggers a change detection cycle each time a scroll event is dispatched. However we only want to show or hide a button at a specific scroll position. Therefore, we only want to refresh our application once.
16+
In this challenge, we only need to refresh the view at a specific scroll position to display or hide a button. All other cycles are unnecessary.
17+
18+
To have a better visualization of the problem, profile your application with Angular Dev Tools.
19+
20+
:::note
21+
If you don't know how to use it, read [the performance introduction page](/challenges/angular-performance/) first and come back after.
22+
:::
1923

20-
> You can vizualise how many times CD is triggered by installing the [Angular chrome devTool](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) and starting a new recording on the profiler tab.
24+
You can learn more details about zone pollution and how to resolve it [here](https://angular.io/guide/change-detection-zone-pollution).
2125

22-
The following video will explain what is the goal of this challenge.
26+
The following video will explain more in-depth the issue of this application.
2327

2428
<video controls src="https://user-images.githubusercontent.com/30832608/209819211-58d9ddcf-e1ad-4a78-8a7a-2be9d729e3f1.mov">
2529
</video>
2630

2731
## Statement
2832

29-
Your goal for this challenge is to avoid all unnecessary change detection cycles and trigger a CD only when needed.
33+
Your goal for this challenge is to avoid all unnecessary change detection cycles and trigger a change detection only when needed.
3034

3135
## Constraint:
3236

33-
You cannot opt-out of zone.js. If this code is part of a large project and you opt out of zone.js, you will break many things within your application.
37+
You cannot opt-out of Zone.js globally. If this code is part of a large project and you opt out of Zone.js, you will break your application without any doubt.
3438

3539
---
3640

docs/src/content/docs/challenges/angular-performance/34-default-onpush.md

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,37 @@ sidebar:
55
order: 34
66
---
77

8-
:::note
9-
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
10-
:::
11-
128
<div class="chip">Challenge #34</div>
139

1410
## Information
1511

16-
In this series of challenges, you will learn how to optimize and enhance the performance of your Angular Application.
12+
In this challenge, we will explore the differences and impacts of using `ChangeDetectionStrategy.Default` versus `ChangeDetectionStrategy.OnPush`.
1713

18-
The first step is to download the [Angular DevTools Chrome extention](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) if you haven't already done so. This extension allows you to profile your application and detect performance issues.
14+
You can read the [Angular documentation](https://angular.io/guide/change-detection-skipping-subtrees) to learn more about the differences between these strategies.
1915

20-
In this challenge, we will explore the differences and impacts of using `ChangeDetectionStrategy.Default` versus `ChangeDetectionStrategy.OnPush`. To provide a clearer demonstration, I have added color enlightment to each component and each row in our application. However, in real-world scenarios, you will not have such visualization. This is where the Angular DevTool profiler comes to the rescue.
16+
In this challenge, all components start with the `Default` strategy. When you type letters inside the input field, you will notice that all components are highlighted in orange.
2117

22-
Start by serving this application by running: `npx nx serve performance-default-onpush` inside your terminal. Then open Chrome DevTool by pressing **F12** and switch to the Angular Tab. From there you can select the Profiler tab as shown below.
18+
:::note
19+
I added color highlighting to each component and each row to provide a better visualization of when a component is rerendered.
20+
:::
2321

24-
![profiler tab](../../../../assets/34/profiler-tab.png 'Profiler tab')
22+
As you can see, each letter triggers a new change detection cycle, and all components are rerendered, causing performance issues.
23+
24+
Let's use the <b>Angular DevTool</b> to profile our application and understand how this tool can help us understand what is happening inside our application.
25+
26+
:::note
27+
If you don't know how to use it, read [the performance introduction page](/challenges/angular-performance/) first and come back after.
28+
:::
2529

26-
Start profiling your application and type some letters inside the input field. You will notice that each element of your application will flash at each change detection cycle and the profiler will show you a bar for each change detection cycle.
30+
Now, start profiling your application and type some letters inside the input field to trigger some change detection cycles.
2731

28-
If you click on one of the bars (indicated by the yellow arrow on the picture below), you can see that `PersonListComponent`, `RandomComponent` and all the `MatListItem` are impacted by the change detection cycle, even when we only interact with the input field.
32+
If you click on one of the bars (indicated by the yellow arrow in the picture below), you can see that `PersonListComponent`, `RandomComponent`, and all the `MatListItem` are impacted by the change detection cycle, even when we only interact with the input field.
2933

30-
![profiler record](../../../../assets/34/profiler-record.png 'Profiler Record')
34+
![profiler record](../../../../assets/angular-performance/34/profiler-record.png 'Profiler Record')
3135

3236
## Statement
3337

34-
The goal of this challenge is to improve the clustering of change detection within the application.
38+
The goal of this challenge is to improve the clustering of change detection within the application using the `OnPush` change detection strategy, but not only...
3539

3640
## Hints:
3741

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
title: 🟢 Memoization
3+
description: Challenge 35 is about learning
4+
sidebar:
5+
order: 35
6+
---
7+
8+
<div class="chip">Challenge #35</div>
9+
10+
## Information
11+
12+
In Angular, <b>pure Pipes</b> are very powerful because the value is memoized, which means if the input value doesn't change, the `transform` function of the pipe is not recomputed, and the cached value is outputted.
13+
14+
You can learn more about pipes in the [Angular documentation](https://angular.io/guide/pipes) and inside this [deep dive article](https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d).
15+
16+
In this challenge, we start with a button to load a list of people. Each person is associated with a number, and we will use the Fibonacci calculation to create a heavy computation that will slow down the application.
17+
18+
Once the list is loaded, try typing some letters inside the input field. You will notice that the application is very slow, even though you are only performing very basic typing.
19+
20+
:::note
21+
We will not focus on the initial loading of the list in this challenge.
22+
:::
23+
24+
Let's use the <b>Angular DevTool</b> to profile our application and understand how this tool can help us understand what is happening inside our application.
25+
26+
:::note
27+
If you don't know how to use it, read [the performance introduction page](/challenges/angular-performance/) first and come back after.
28+
:::
29+
30+
Now, start profiling your application and type some letters inside the input field. You will see some red bars showing up inside the profiler panel.
31+
32+
If you click on one of the bars (indicated by the yellow arrow in the picture below), you will see that the change detection cycle is taking more than 3s in `PersonListComponent`.
33+
34+
![profiler record](../../../../assets/angular-performance/35/memoize-profiler.png 'Profiler Record')
35+
36+
## Statement
37+
38+
The goal of this challenge is to understand what is causing this latency and to improve it.
39+
40+
## Hints:
41+
42+
<details>
43+
<summary>Hint 1</summary>
44+
45+
Use `Pipes` to memoize the Fibonnaci computation.
46+
47+
</details>
48+
49+
---
50+
51+
:::note
52+
Start the project by running: `npx nx serve performance-memoized`.
53+
:::
54+
55+
:::tip[Reminder]
56+
Your PR title must start with <b>Answer:35</b>.
57+
:::
58+
59+
<div class="article-footer">
60+
<a
61+
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A35+label%3Aanswer"
62+
alt="Memoization community solutions">
63+
❖ Community Answers
64+
</a>
65+
<a
66+
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A35+label%3A"answer+author"'
67+
alt="Memoization solution author">
68+
▶︎ Author Answer
69+
</a>
70+
</div>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
title: Angular Performance
3+
prev: false
4+
next: false
5+
description: Challenge 34 is about learning the difference between Default and OnPush Change Detection Strategy.
6+
sidebar:
7+
order: 1
8+
---
9+
10+
import { LinkCard } from '@astrojs/starlight/components';
11+
12+
In this series of challenges about performance, you will learn how to optimize and enhance the performance of your Angular application.
13+
14+
Before starting to resolve any challenge, I invite you to download the [Angular DevTools Chrome extention](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) if you haven't already done so.
15+
16+
This extension allows you to profile your application and detect performance issues, which is very useful for understanding where performance issues can occur.
17+
18+
## How to use it
19+
20+
When you serve an Angular application, you can inspect a page by pressing <b>F12</b>, which will open the <b>Chrome developer tools</b>. Then navigate to the <b>Angular tab</b>. From there, you can select the <b>Profiler tab</b> as shown below.
21+
22+
![profiler tab](../../../../assets/angular-performance/profiler-tab.png 'Profiler tab')
23+
24+
You can now profile your application by clicking on the record button. You can play with your application and see when change detection is triggered and which components are rerendered.
25+
26+
:::tip[Learn more]
27+
You can learn more on the [documentation page](https://angular.io/guide/devtools).
28+
:::
29+
30+
Now that you know how to use the <b>Angular DevTool</b>, you can choose a challenge, profile it, and resolve it.
31+
32+
<LinkCard
33+
title="🟠 Optimize Change Detection"
34+
description="Learn how to remove zone pollution."
35+
href="/challenges/angular-performance/12-scroll-cd/"
36+
/>
37+
38+
<LinkCard
39+
title="🟢 Default vs OnPush"
40+
description="Learn the difference between Default and OnPush change detection strategies."
41+
href="/challenges/angular-performance/34-default-onpush/"
42+
/>
43+
44+
<LinkCard
45+
title="🟢 Memoization"
46+
description="Learn the power of pure pipes."
47+
href="/challenges/angular-performance/35-memoize/"
48+
/>

docs/src/content/docs/challenges/angular-performance/32-bug-cd.md renamed to docs/src/content/docs/challenges/angular/32-bug-cd.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ WIP: The following documentation will be reviewed and improved. However, you can
1111

1212
<div class="chip">Challenge #32</div>
1313

14+
:::note
1415
This challenge is inspired by a real-life example that I simplified to create this nice challenge.
16+
:::
1517

1618
## Information
1719

18-
In this small application, we have a navigation menu to route our application to either `barComponent` or `FooComponent`. However our application is not loading and no errors are displayed inside the console.
20+
In this small application, we have a navigation menu to route our application to either `BarComponent` or `FooComponent`. However our application is not loading and no errors are displayed inside the console.
1921

2022
## Statement
2123

docs/src/styles/custom-css.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ b {
9494
color: var(--sl-color-accent-high);
9595
}
9696

97+
.starlight-aside--tip b {
98+
color: var(--sl-color-asides-text-accent);
99+
}
100+
97101
.main-page-footer {
98102
margin-top: 2rem !important;
99103
font-size: var(--sl-text-sm);

example.README.md

Lines changed: 0 additions & 45 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"start": "nx serve",
99
"build": "nx build",
1010
"test": "nx test",
11-
"prepare": "husky install"
11+
"prepare": "husky install",
12+
"doc:dev": "cd docs && npm run dev"
1213
},
1314
"private": true,
1415
"dependencies": {

0 commit comments

Comments
 (0)