Performance considerations when using filters

Loading

Filters in AngularJS are powerful tools for transforming and displaying data in real time. However, improper use can lead to performance issues, especially when working with large datasets or frequent UI updates. This guide will help you understand the performance impact of filters and how to optimize them.


1. Why Filters Can Impact Performance?

AngularJS filters are re-evaluated on each digest cycle, which means:
Every time a scope variable changes, AngularJS re-runs the filters.
When used in ng-repeat, filters are applied to every item in the list.
Complex filters like sorting and searching can be computationally expensive.


2. Performance Issues When Using Filters

Here are some common performance problems caused by excessive or improper filter usage:

Filters in ng-repeat (Slows Down Large Lists)

Using filters directly inside ng-repeat applies them on every digest cycle for all items in the array.

Inefficient Usage

<li ng-repeat="user in users | filter:searchText | orderBy:'name'">
{{ user.name }}
</li>

Issue: If users contains thousands of items, the filter will run every time AngularJS checks for changes, leading to lag.


Filters in Expressions (Unnecessary Recomputations)

AngularJS recomputes the filter on every digest cycle, even if the data has not changed.

Inefficient Usage

<p>{{ longText | limitTo:100 }}</p>

Issue: If longText doesn’t change, there’s no need to re-run the filter on every scope update.


3. Optimizing Filter Performance

3.1 Use Filters in Controllers Instead of Views

Move filters out of the template and into the controller, so they execute only when needed.

Optimized Usage (Pre-filter in Controller)

app.controller('UserController', function($scope, $filter) {
$scope.filteredUsers = $filter('filter')($scope.users, 'John');
});
<li ng-repeat="user in filteredUsers">
{{ user.name }}
</li>

Benefit:

Runs once instead of every digest cycle
Reduces CPU load, improving UI performance


3.2 Avoid Filters in ng-repeat

Instead of applying filters inside ng-repeat, precompute filtered data.

Bad Practice (Recomputes on Every Digest Cycle)

<li ng-repeat="user in users | filter:searchText | orderBy:'name'">
{{ user.name }}
</li>

Optimized Approach (Filter Data in Controller)

app.controller('UserController', function($scope, $filter) {
$scope.$watch('searchText', function(newVal) {
$scope.filteredUsers = $filter('filter')($scope.users, newVal);
});
});
<li ng-repeat="user in filteredUsers">
{{ user.name }}
</li>

Benefit:

Filters apply only when searchText changes, not on every digest cycle
Speeds up rendering for large datasets


3.3 Use track by in ng-repeat

Using track by prevents AngularJS from recreating DOM elements unnecessarily.

Bad Practice (Default Re-evaluation)

<li ng-repeat="user in users">
{{ user.name }}
</li>

Optimized Approach (track by user.id)

<li ng-repeat="user in users track by user.id">
{{ user.name }}
</li>

Benefit:

Prevents unnecessary DOM re-rendering
Improves list rendering performance


3.4 Cache Filtered Results

Instead of filtering every time, store the filtered data in a cache.

Using $watch to Cache Filtered Data

app.controller('UserController', function($scope, $filter) {
$scope.$watchGroup(['users', 'searchText'], function() {
$scope.filteredUsers = $filter('filter')($scope.users, $scope.searchText);
});
});

Benefit:

Filters only update when data changes
Improves responsiveness in large lists


3.5 Use One-Time Binding (::) Where Possible

One-time binding (::) ensures that filters run only once.

Recomputed on Every Digest Cycle

<p>{{ message | uppercase }}</p>

Optimized (One-Time Binding)

<p>{{ ::message | uppercase }}</p>

Benefit:

Filters don’t re-run unless message changes
Reduces CPU overhead


3.6 Use Custom Filters for Complex Logic

If the filter logic is complex, implement a custom filter in JavaScript.

Example: Custom Search Filter

app.filter('customSearch', function() {
return function(items, searchText) {
if (!searchText) return items;
return items.filter(item => item.name.toLowerCase().includes(searchText.toLowerCase()));
};
});
<li ng-repeat="user in users | customSearch:searchText">
{{ user.name }}
</li>

Benefit:

Custom filter optimizes search logic
More efficient than Angular’s default filter

Leave a Reply

Your email address will not be published. Required fields are marked *