Software systems to innovate and grow

Common Problems and Solutions to Help Improve Angular Performance

By Engineering Team August 8, 2018 10 mins read

In this article we will discuss common issues that come up in every Angular app. In addition, we will offer solutions by teaching you how to access a quick boost in performance.

Take Advantage of Lazy Loading

Once your app grows in size, it’s time to split the features into modules. This will help to optimize the organization and give you the ability to enable lazy loading. The default of Angular CLI combined with Webpack will deliver your application code into one large bundle. With lazy loading, you can load features on-demand as they are needed, making the initial loading time of your application faster. This process is done transparently through Angular.

With the usage of guards and a few preset conditions, you can avoid the headache of loading whole modules. We recommend having resource routes protected, it’s a common solution when building big applications that are going to be used by users with different roles and privileges. Angular routers provide navigation guards to accomplish this task easily. This means, in addition to preventing a user from accessing a resource, you can protect your code from being loaded and stolen with the canLoad guard. The user management module will block a user if the user does not have the required privileges.

Loops

A common performance issue that Angular applications has is it’s often generated when rendering elements inside a loop. Let’s say you want to render a list of users, and do something like this:

The issue appears when we add, modify, or update to a user inside the userList. Since Angular cannot identify which element has changed, you’ll end up rendering all the elements of the list again. Solutions such as DOM operations are really expensive, yet it would be wise to avoid having Angular create all the sibling nodes with a collection if a single nodes being added, removed or modified. The better solution is to make use of a tracking mechanism to help Angular avoid rendering every element in the list again. This can be achieved using the trackBy property.

After, you’ll need to create a trackBy function in your ts file, like this:

Specifying trackBy in Angular ng loops helps it to identify the rows being added or removed when the data of the application changes. This way you are optimising your loops.

Modify The Change Detection Mechanism

Let’s say you are building a component that displays and changes data continually. Each time the data is changed, your view will be re rendered. If we think of a scenario where this happens many times per second, your app will constantly try to render the new value. You already know that DOM operations are too expensive, so the long hand option is to update the user interface every time new data arrives; but with all the changes, it can kill your app performance. A more efficient solution would be to check and render the component within a fixed amount of time. This can be done by having the component’s change detector and detached, and through running a local check every x number of seconds.

Observables and Subscriptions

While working with reactive programming, Observables allows much richer service compositions and facilitates, allowing you to create complex data flows; but gives you the added responsibility of unsubscribing from all your data at the right time. In a large application you subscribe to a large number of events and observables to maintain the components updated to change. As a result of the quantity of manual work, a common mistake people make is they forget to unsubscribe. This can cause unexpected side effects, and may consume a good share of performance quality— especially if that component is being repeated in loop. Angular calls for the ngOnDestroy lifecycle hook method once a component is no longer used. The tool is placed at the end of our subscriptions.

We store a Subscription instance for every Observable.subscribe() and call to the unsubscribe method inside ngOnDestroy. Though it’s helpful, it can become a bit tedious when you have lots of subscriptions. A better solution is to use the takeUntil operator to declaratively manage the component subscriptions.

With this method, you are able to have control over every subscription through automatic halting after ngOnDestroy(). It looks cleaner and is more reliable as an error proofer than doing all the work manually.

Template Functions

Many times you find yourself in a position where you are needing to modify a value that comes from the server and changes it to something you can display in the view.

For example:

The problem here appears because Angular will execute the function in every change detection cycle and if the function is doing some heavy processing, it may negatively impact your app performance. If you know the result of your function will not be changed dynamically at runtime beforehand, a solution is to:

  1. Use pure pipes.  Angular executes a pure pipe only when it detects a pure change to every input value.
  2. Create new properties in your model and calculate the values only once each.
    For example:

Angular’s applications have improved the performance between the appearance of each new version of the framework, however, there are many situations to caution as they create unintended performance bottlenecks. Knowing where to look is sometimes difficult, but by using the solutions in this article, an Angular developer can easily prevent unintended performance hindrances from happening. And now, you have some new knowledge to add to your toolbelt on how to optimally use Angular’s resources.