If you feel that your Angular Templates application is running slow and you want it to have a better performance, you may not have noticed some aspects that make an application run optimally, Angular by default is a fast and high-performance Framework and We should not have many problems with it, but in this Post I am going to share some details that may be making your application slow.
There are many popular tips and resources for improving the performance of an application built with Angular, most tips are good and valid, but often not much is said about the issues that cause poor application performance.
These usually happen when micro optimization tasks are carried out, here are a couple of situations where Developers often make this decision:
- “We’re using too much reduction, map and filter, let’s replace them all with loops! “
- “! Let’s use a dictionary to access the data faster! “
The above situations are very common and there may be other similar cases, the first thing Developers do when they are trying to find the reason why they are experiencing poor performance in their application, is a debug on each call to a certain function:
You Can Question 2 Other Possible Problems:
- How much does the application actually render?
- How often does the Framework re-render components?
We can see that although best practices are followed, sometimes they are not enough to avoid slow application performance, there are always things to improve.
Most of the time it is not due to the Framework we are using, but to the architecture of our code.
The Application Is Processed Too Frequently
This problem is very common, the application re-processes components unnecessarily, making the application slower than normal, this is sometimes difficult to solve, but obviously easy to cause.
1. Change detection
You can set change detection (ChangeDetectionStrategy) in OnPush , this should be an almost mandatory decision if your application suffers from slow performance or if you want to prevent it from happening in the future.
By configuring the application components to update only on the fly, you avoid re-generating components that do not need to be parsed. It is simple and its use is greatly simplified when using Observables and AsyncPipe .
2. Async Pipe
Even if you use OnPush and AsyncPipe in your templates, you can render elements that you don’t need.
Preventing Observables from being emitted is a good way to prevent a component from being re-rendered, we can use operators like filter and distincUntilChanged to skip re-renders entirely.
Another problem that usually happens when using Observables and AsyncPipe, is when records or data are selected without using selectors, when using selectors, we only receive updates from the affected state segment.
If we select the whole object of a Redux state tree, the selectors will emit every time the tree changes and as a result we will end up activating updates in components that are practically not affected.
3. High Frequency Updates
This case is not a very common problem in Angular Template, it is probably due to the Zone.js dependency which magically detects changes in the code of an application.
Zone.js detects all changes made in the code, this means that if the application is transmitting events at a fast speed through Websocket or DOM events. For each event performed, Zone will trigger a change detection.
We can separate the affected components, then update them manually when updates are notified. We can make use of the ngZone.runOutsideAngular callback to execute the response of a call outside of Angular’s ChangeDetectionStrategy.
A last resort is to exclude the particular event caught by Zone.js. It is important to make use of the tools that angular offers us in its documentation.
Your Application Renders A Lot Of Non-optimized Elements
No matter how fast Angular or the framework we are using is. If it is processing thousands of complex components at once. The browser will eventually show a certain amount of delay when loading a project.
We must consider that the components represent many elements and must be optimized in a particular way, we can solve this in the following ways:
This is a simple and perhaps well-known technique, it is widely used in most packages, libraries or dependencies. This concept is simple, we assign a key to each element of a list and the library will re-render it only if the key has changed.
2. Virtual scrolling
This only represents what the user wants to see. Although this has no accessibility / usability implications to take into account. It is one of the best methods to improve the performance of the application and prevents the page from freezing for a period of time unreasonable.
3. Async Rendering
This technique is old enough and I would rather use Virtual Scrolling. But it may still be better to render 1000 elements at once and it is very easy to implement without having to write a lot of code.
The concept is as follows: start rendering a limited number of elements. Say 50 out of 500 elements, then schedule a subsequent rendering with the next 50 elements using the setTimeout (0) method until all elements are displayed. This is a very simple technique, so the results are simple too. And the browser won’t get stuck for long when processing the items.
4. Lazy Rendering
We can create an instance of the component when the user needs it. For example when the user scrolls or clicks on it. With this almost all performance problems will disappear and the application will load optimally.
5. Lazy Listeners
If you have a very large list of elements in the DOM. Be sure to run events with only the elements that are visible in the interface.
Sometimes we can create a single global event from a Service. Instead of creating an event in each Directive or Component.
If you analyzed and found that your application does not run processes very often. Then your code may be quite slow. This is probably due to some heavy scripts and they are not DOM related.
Luckily There Are Tools To Solve These Types Of Problems Today:
You can use WebWorkers , the Angular CLI also provides a command to generate a WebWorker instantly. With this technology you can execute code in parallel without directly affecting the angular code.
You can also use WebAssembly, there is the AssemblyScript library that can help you with that.
If the aforementioned is not enough for you. You can try micro optimizations and verify how much it can improve performance in the execution of the application processes:
Use A Custom IterableDiffers .
Convert everything to loops, have use of filters, reduce and map. Use break and continue to reduce the number of iterations.
These are some tips that can help you optimize your application. If you know some others, you can write them in the comments.