![]()
What You’ll Learn
Common performance bottlenecks in AngularJS
Techniques to optimize the digest cycle
Best practices for controllers, services, and directives
Efficient API handling and memory management
1️⃣ Optimize the Digest Cycle
AngularJS runs a digest cycle to check for changes in scope variables. If your app has too many watchers, the digest cycle slows down.
Best Practices:
✔ Minimize Watchers: Avoid unnecessary $watch(), $digest(), and $apply() calls.
✔ Use One-time Binding (::) for Static Data:
htmlCopyEdit<h1>{{::title}}</h1>
Prevents re-evaluation of unchanging values.
✔ Use track by in ng-repeat to Prevent Re-renders:
<li ng-repeat="item in list track by item.id">{{ item.name }}</li>
Prevents unnecessary DOM updates when data changes.
2️⃣ Reduce DOM Manipulation
Direct DOM access in AngularJS slows down the application.
Best Practices:
✔ Avoid ng-show/ng-hide for Large DOM Elements
Instead, use ng-if to remove elements from the DOM when not needed.
<div ng-if="isVisible">Content</div>
✔ Use $compile() Only When Necessary
Compiling large templates dynamically can be slow.
✔ Use Virtual Scrolling for Large Lists
Instead of rendering thousands of elements, render only what’s visible.
3️⃣ Optimize API Calls and Data Handling
Too many HTTP requests and large data sets slow down performance.
Best Practices:
✔ Use $cacheFactory for Caching API Responses
app.factory('DataService', function ($http, $cacheFactory) {
var cache = $cacheFactory('dataCache');
return {
getData: function (url) {
if (!cache.get(url)) {
cache.put(url, $http.get(url));
}
return cache.get(url);
}
};
});
Prevents repeated API calls for the same data.
✔ Debounce API Calls in Search Input (ng-model-options)
<input type="text" ng-model="search" ng-model-options="{ debounce: 300 }" ng-change="fetchData()" />
Reduces unnecessary API calls while the user is typing.
✔ Use $q.all() for Parallel API Calls
$q.all([getUsers(), getOrders()]).then(function (results) {
$scope.users = results[0].data;
$scope.orders = results[1].data;
});
📌 Runs multiple API calls simultaneously to improve speed.
4️⃣ Improve Memory Management
Memory leaks can slow down and crash AngularJS apps over time.
Best Practices:
✔ Destroy $watch Listeners When Not Needed
var unbindWatcher = $scope.$watch('variable', function (newVal) {
console.log(newVal);
});
$scope.$on('$destroy', function () {
unbindWatcher();
});
📌 Prevents unused watchers from consuming memory.
✔ Remove Event Listeners in $destroy
element.on('click', function () {
console.log('Clicked');
});
$scope.$on('$destroy', function () {
element.off('click');
});
Prevents memory leaks from event listeners.
✔ Use $timeout Instead of setTimeout
$timeout(function () {
console.log('Delayed execution');
}, 1000);
$timeout ensures automatic cleanup when the scope is destroyed.
5️⃣ Optimize Directives for Performance
Poorly written directives can slow down rendering.
Best Practices:
✔ Use bindToController Instead of $scope
app.directive('exampleDirective', function () {
return {
restrict: 'E',
scope: {},
bindToController: {
data: '='
},
controllerAs: 'ctrl',
controller: function () {
console.log(this.data);
}
};
});
Improves isolation and performance.
✔ Use compile Instead of link for Template Optimization
compile: function (element) {
return function link(scope) {
// DOM manipulation here
};
}
Pre-compiling templates reduces re-rendering overhead.
6️⃣ Use Lazy Loading for Modules
If your app is large, load components only when needed to improve performance.
Best Practice: Lazy Load Controllers
var app = angular.module('myApp', ['oc.lazyLoad']);
app.config(function ($stateProvider) {
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
controller: 'DashboardController',
resolve: {
loadCtrl: function ($ocLazyLoad) {
return $ocLazyLoad.load('dashboardController.js');
}
}
});
});
Loads controllers only when the route is accessed.
7️⃣ Minimize Filters and Expressions in Templates
Filters and expressions inside templates slow down rendering.
Bad Practice:
<p>{{ largeArray | filter: 'active' }}</p>
Runs filter on every digest cycle!
Best Practice:
$scope.filteredData = $filter('filter')(largeArray, 'active');
<p>{{ filteredData }}</p>
Applies filter only once instead of on every update.
8️⃣ Use AngularJS Batarang for Debugging
AngularJS Batarang is a Chrome extension for analyzing performance bottlenecks.
Best Practices:
✔ Identify slow digest cycles
✔ Find unused watchers
✔ Optimize bindings and API calls
Install from Chrome Web Store and inspect AngularJS performance!
