The Cardinal Sin of Angular: Using Functions Instead of Pipes

Using functions instead of pipes in views can lead to suboptimal performance.

berastis
Bits and Pieces

--

As developers, we are always looking for ways to optimize our projects and ensure they run smoothly. In Angular, one common mistake that can lead to suboptimal performance is using functions instead of pipes in views. In this article, we will discuss the consequences of committing this cardinal sin, and show examples of how frequently functions and pipes are called in views.

The Angular Crime: Functions Instead of Pipes

In Angular, you might be tempted to use a function directly in a view to manipulate data, as it seems like an easy solution. However, this is where the trouble begins. Functions called in views can lead to unnecessary performance issues due to the way Angular handles change detection. In contrast, pipes are designed specifically for data transformation in views, making them the optimal choice.

Let’s examine the difference between how often functions and pipes are called in views to better understand the impact on performance.

Functions in Views: A Recipe for Performance Issues

When using a function in an Angular view, the function is called every time the view is checked for changes, regardless of whether the input data has changed. This means that the function is executed far more often than necessary, leading to decreased performance.

For example, imagine an Angular component with the following code:

@Component({
selector: 'app-example',
template: `
<div *ngFor="let item of items">
{{ transformData(item) }}
</div>
`,
})
export class ExampleComponent {
items = [/* ... */];

transformData(item) {
// Data transformation logic
}
}

In this example, the transformData() function is called for every item in the items array whenever change detection runs. If there are 100 items in the array, the function will be called 100 times, even if none of the items have changed.

Pipes: A More Performant Alternative

On the other hand, Angular pipes are called only when the input data changes or when the pipe’s parameters are modified. This makes pipes a much more efficient choice for data transformation in views.

To illustrate this point, let’s refactor the previous example to use a pipe instead of a function:

@Pipe({
name: 'transformData'
})
export class TransformDataPipe implements PipeTransform {
transform(item: any): any {
// Data transformation logic
}
}

@Component({
selector: 'app-example',
template: `
<div *ngFor="let item of items">
{{ item | transformData }}
</div>
`,
})
export class ExampleComponent {
items = [/* ... */];
}

With the pipe implementation, the transformData pipe is called only when the data in the items array changes. If there are no changes, Angular skips the execution of the pipe, resulting in better performance.

💡 You could extract this code away into something that you could reuse across projects with a simple npm i @bit/your-username/custom-pipe-name with Bit, an open-source toolchain for Angular code sharing.

Find out more here:

Conclusion

Using functions instead of pipes in Angular views is a cardinal sin that can lead to poor performance due to the excessive calls to functions during change detection. Pipes are specifically designed for data transformation in views and offer a more efficient alternative.

To avoid this Angular crime, always consider using pipes for data transformations in your views. It’s a simple change that can have a significant impact on the overall performance of your application.

Build Angular Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

--

--