Angular Optimization. Memoized pipe functions in templates.

Artem Lanovyy
6 min readJan 23, 2019

--

If you could optimize — optimize it now.

Nowadays we always try to be on a short leg with the current rapidly developing technologies and optimize our applications to make them faster, provide better user experience or update legacy code. If You are reading this article, then you’re looking for new approaches or You have an interest in how to upgrade your application and make it cooler. So, let’s begin!

Optimization in Angular application could be reached by passing some points, like: Correct decomposition of components; Using change detection strategy OnPush; Managing all subscriptions in the project. We have plenty of ways to do that, however, today I will try to explain one uncommon and rarely used case, nevertheless, it’s worth a lot and could increase the performance of our applications and make them more optimized.

In case You know everything and just want the result — scroll to the bottom of this article and meet the library and examples there.

Meet the Pure Pipes — one more optimization strategy but it isn’t widely known and used. Mayhap, it’s because of the inconvenience of using such an approach or something different, let’s figure out.

So when we are talking about the Angular pipes, we could reach from Angular guide, that we have two variants of them: pure and impure pipes.

So let’s highlight some parts from the documentation.

Angular executes an impure pipe during every component change detection cycle. An impure pipe is called often, as often as every keystroke or mouse-move.

It’s not the one we are looking for when we are talking about optimization. However, we have another variant called pure pipe. Let’s investigate that moment:

Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).

So, that's already what we are looking for when talking about optimization. We are trying to reduce not only change detection calls but also a recomputation of functions. And here we could see, that pure pipe behaves like memoization technique.

In computing, memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

Recomputation of functions is an optimization problem, consists of minimizing a call of the function to provide minimum unnecessary executions and system load.

So let’s turn to examples!

Act 1 — Exposition

We know how change detection works. We have 2 different variants of change detection strategy: Default and OnPush. Let’s test our pure pipes with all of them and figure out the difference.

We will create a simple Application which will convert text to base-64 encoded format. Each time, when the functioncompile will execute we will print console log.

Firstly, let’s see an example with Default strategy and unoptimized code:

When we run this code, we will see such output in the console:

The result of running the unoptimized code

Right now someone could tell to use the change detection strategy — OnPush and he will be right. Let’s look at how it will optimize that function execution.

Optimized with OnPush strategy

However, if we go deeper, we could check the situation when even with the Change Detection strategy OnPush we could see redundant executions.

Change detection with OnPush strategy run in such cases:

  • Manual call Change Detection with methods
  • Events in component and its children
  • Change in Input decorated reference (@Input)

So let’s modify the example and add more “events” to our code like input filed with ngModel and button with the function for changing the name.

Right now, when you will write down something in the input field, it will trigger the change detection and recompute our function every time.

OnPush change detection recompute our function

You could read more about why and what will trigger the change detection with OnPush strategy here, yet, let’s try to solve our optimization issue.

Act 2 — Climax

So then, let’s use our knowledge from Angular Documentation and use the Pure Pipe to solve this issue.

We could rewrite our compile function to the pipe like so

And the output again will be optimized even with the change detection updates. No more redundant calls.

Pure Pipe optimization

We solve the issue with the recomputation, however, right now we could imagine, why people do not use such an approach. You will never rewrite your executable functions in templates to the pure pipes cuz you're not crazy. It’s totally not useful. So, do we have a variant for solving this?

Act 3 — Resolution

Finally, what if we create a single pure pipe function, which will take another function and call it with the optimization as the pure pipes have.

We won't create pipes for each function in the template and we will reach the optimization point, which we are looking for.

Let’s take a look at such function.

That pipe function simply takes the value as a first argument and a callback function (handler) which is responsible for the computation as a second. So the output is a call of the callback function with the input value argument.

And let’s use this function in our example!

And now, we have the same result comparable with the one, when we created a special pipe for our function.

Using pipeFunction with the custom method

Library

For that case, I have created a small library, which will provide a simple solution for the realization of such pipe in the Angular and which provide more complex examples for multiple arguments and context binding in functions.

For example, you could freely use such code, even with the pure pipes:

Let’s upgrade our function compilewith this.surname. In the template, we add this keyword in our arguments for pipeFunction to bind our updated function to context correctly. (PS: Moreover, you could manage it with thebind method in the template)

And the final result is:

You could find everything here.

Ending

I hope that You have found something new for yourself and your Angular project in this article. I will try to highlight more optimization topics and real working code examples in the future. I wish you good luck in programming and optimization.

📝 Read this story later in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--

Artem Lanovyy

Digital trailblazer & tech aficionado, exploring the web, connecting with vibrant communities, seeking knowledge to unlock e-verse treasures!