May 10, 2019

Optimize the performances of large tables in your Angular application

Challenge

If you are working with tables which have a big amount of rows and columns, the performance can get worse if you don’t care for it. Especially if you have a large table with a lot of FormGroups inside.

The following steps should clean up your code and increase the performance of your grid measurably.

1. Change detection strategy: OnPush

Most of the time, the change detection of Angular feels like a nice magic, that makes your life much easier. But if you have a large app with a big amount of values, you will realize, that the change detection is a complex thing, that makes your app sometimes a bit slow.

If a value in your template is changed, Angular checks each value in the view for updates. Doing this, Angular compares the old value with a supposed new value. Depending on the amount of data this can take a lot of time. To fix this problem, it is possible to change the change detection strategy of Angular on the component level.

After this change, angular only goes for a deep check, if the input (@Input) reference of a value has changed. Otherwise Angular will only do a references check. If the references of the variable changed, Angular will compare both values like mentioned before.

Now you have to care to use immutable objects. Make sure to always create a new object instead of manipulating the old one, so the object gets a new reference and the change detection will work as expected. Using the OnPush strategy should significantly reduce the change detection calls.

Angular also provides a way to trigger the change detection programmatically. Maybe it could be useful to trigger the change detection every few seconds programmatically, instead of triggering the change detection automatically every time a value has changed.

Therefor take a look at this snippet:

For more information read here.

2. The updateOn property

Each FormGroup has a property called updateOn. This property determines when the form validations for the current form group is called. Possible values are change (default), submit and blur.

default: Form validations is always called when the value is changed

blur: Form validation is called, when you are leaving the input field

submit: Form validation is called, when you submit the form

We change the updateOn property to blur and as result after leaving the input field the change detection is called the first time. Otherwise the form validation will be called every time we make changes inside the input field. Depending on the use case of the application the submit or blur property could be the better choice and will offer always a better performance.

3. Form validators

The construction of form validations for a table is based on one parent form group containing one form group for each row in the table.

Pay attention, that the validation function is attached to the hierarchically lowest point that is possible. For example, there is a field called age, which is not allowed to be zero. Now you should attach your custom form validator to the age field and not to the whole form group it belongs to.

The required function is only called if the value of the age field is changed. If we attach the validator to the complete group, the form validation function is called when any value of the form group is changed.

4. Pure pipes instead of functions calls

Sometimes you might want to manipulate data in the template directly. We want to avoid unnecessary calls, so we should choose to implement a pipe instead of call a function inside the template.

A pure pipe is just called if the reference (Objects or Arrays) or the value (string/number/boolean) of the current field is changed.

If you use a function or an impure pipe, the function or impure pipe is called in every change detection lifecycle.

Check this out for a detailed explanation and a clean example.

5. Virtual scrolling

Angular provides the opportunity, to render only the part of the table, that is currently in the view. Less resources are needed for rendering the full table, more resources are available to calculate other stuff.

Check this out for a full implementation.

6. trackBy function

For example you have a dropDown list with a lot of items (using *ngFor). Now you are constantly adding and removing items to the list. Angular renders the full list, because Angular doesn’t know which item has changed. To avoid unnecessary rendering you can use the trackBy function.

If you want to read more about trackBy click here.

7. Always unsubscribe

Always make sure to unsubscribe to avoid memory leaks. For example if you use a subscription for the valueChanges of your form group, pay attention to unsubscribe at the latest in the ngOnDestroy function. If you don’t, Angular will not throw away the subscription until all subscribers are unsubscribed. You can also use a library, that takes care about it.

Related Posts

Lino Fischer
Developer at thecodecampus </>


Leave a Reply

Add code to your comment in Markdown syntax.
Like this:
`inline example`

```
code block
example
```

Your email address will not be published.