Lazy Loading AngularJS Controller Files Using RequireJS

In this article, we will discuss how to load AngularJS controller file at run time for a single page application.

AngularJS has become very popular for web development in today's development world. The main advantage of AngularJS is that we can use two way binding of data with the help of AngularJS for a single page application. The main advantage of the single page application is that when the user switches between different pages, there is no full post at the back of the page. Child page always loads within the content of the main page. But if the project contains so many files, say 100 html files, then there are also 100 js files for AngularJS controller files. And for working it properly we need to take the reference of all js files on the home page. In such a way, home page loading will be slow due to downloading the huge number of JavaScript files. 
 
This problem can be solved by the lazy loading concept. For downloading javascript file using lazy loading, we need to use RequireJS.  Actually, RequireJS can dynamically resolve the downloading request of javascript files at the run time. It does not load the files in the beginning. When the user clicks on the link and the page is loading at that timethe  javascript file is automatically loaded. Once the file has been downloaded, then it does not load in the next request.
 
For doing this, we first need to create the AngularJS App as below. For configuring Require js, we need to register the controller method with the angular app config and for working Require js properly, we need to define the route key of the page redirection so that it can dynamically resolve the js file request. For this add a javascript file named testapp.js and write down the following code, 
  1. 'use strict';  
  2. var testApp = angular.module('TestApp', ['ngRoute']);  
  3. var $routeData;  
  4.   
  5. testApp.config(["$routeProvider""$controllerProvider""$compileProvider"function ($routeProvider, $controllerProvider, $compileProvider) {  
  6.     $routeData = $routeProvider;  
  7.     testApp.register =  
  8.             {  
  9.                 controller: $controllerProvider.register,  
  10.                 directive: $compileProvider.directive  
  11.             };  
  12. }]);  
  13.   
  14. testApp.run(['$route''$http''$rootScope',  
  15.     function ($route, $http, $rootScope) {  
  16.         $routeData  
  17.             .when('/home', {  
  18.                 templateUrl: '../../Article/LazyLoadingJs/Home.html'  
  19.             })  
  20.             .when('/P1', {  
  21.                 controller: 'PageController1',  
  22.                 templateUrl: '../../Article/LazyLoadingJs/Page1.html',  
  23.                 controllerAs: 'model',  
  24.                 resolve: {  
  25.                     resolver: ['$q''$rootScope'function ($q, $rootScope) {  
  26.                         var deferred = $q.defer();  
  27.                         require(['../../Article/LazyLoadingJs/Page1'], function () {  
  28.                             $rootScope.$apply(function () {  
  29.                                 deferred.resolve();  
  30.                             });  
  31.                         });  
  32.                         return deferred.promise;  
  33.                     }]  
  34.                 }  
  35.             })  
  36.             .when('/P2', {  
  37.                 controller: 'PageController2',  
  38.                 templateUrl: '../../Article/LazyLoadingJs/Page2.html',  
  39.                 controllerAs: 'model',  
  40.                 resolve: {  
  41.                     resolver: ['$q''$rootScope'function ($q, $rootScope) {  
  42.                         var deferred = $q.defer();  
  43.                         require(['../../Article/LazyLoadingJs/Page2.js'], function () {  
  44.                             $rootScope.$apply(function () {  
  45.                                 deferred.resolve();  
  46.                             });  
  47.                         });  
  48.                         return deferred.promise;  
  49.                     }]  
  50.                 }  
  51.             })  
  52.             .when('/P3', {  
  53.                 controller: 'PageController3',  
  54.                 templateUrl: '../../Article/LazyLoadingJs/Page3.html',  
  55.                 controllerAs: 'model',  
  56.                 resolve: {  
  57.                     resolver: ['$q''$rootScope'function ($q, $rootScope) {  
  58.                         var deferred = $q.defer();  
  59.                         require(['../../Article/LazyLoadingJs/Page3.js'], function () {  
  60.                             $rootScope.$apply(function () {  
  61.                                 deferred.resolve();  
  62.                             });  
  63.                         });  
  64.                         return deferred.promise;  
  65.                     }]  
  66.                 }  
  67.             })  
  68.             .when('/', { templateUrl: '../../Article/LazyLoadingJs/Home.html' });  
  69.     }]);  
  70.   
  71. function resolver($q, $rootScope, dependencies) {  
  72.     var deferred = $q.defer();  
  73.     require(dependencies, function () {  
  74.         $rootScope.$apply(function () {  
  75.             deferred.resolve();  
  76.         });  
  77.     });  
  78.     return deferred.promise;  
  79. }  
HomePage.Html
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4.     <title>Single Page Application</title>  
  5.     <link href="../../RefStyle/bootstrap.min.css" rel="stylesheet" />  
  6.     <script src="../../Scripts/angular.min.js"></script>  
  7.     <script src="../../Scripts/angular-route.min.js"></script>  
  8.     <script src="../../Scripts/require.js"></script>  
  9.     <script src="testApp.js"></script>  
  10.     <script src="IndexController.js"></script>  
  11. </head>  
  12. <body data-ng-app="TestApp" data-ng-controller="IndexController as model">  
  13.     <div class="row animated fadeInRight">  
  14.         <div class="col-lg-12">  
  15.             <div class="rowDiv">  
  16.                 <h3>{{model.message}}</h3>  
  17.             </div>  
  18.         </div>  
  19.         <div class="rowDiv">  
  20.             <div class="col-lg-3">  
  21.                 <a data-ng-click="model.pageChanage(0);">Home</a>  
  22.             </div>  
  23.             <div class="col-lg-3">  
  24.                 <a data-ng-click="model.pageChanage(1);">Page 1</a>  
  25.             </div>  
  26.             <div class="col-lg-3">  
  27.                 <a data-ng-click="model.pageChanage(2);">Page 2</a>  
  28.             </div>  
  29.             <div class="col-lg-3">  
  30.                 <a data-ng-click="model.pageChanage(3);">Page 3</a>  
  31.             </div>  
  32.         </div>  
  33.         <hr />  
  34.         <div class="col-lg-12">  
  35.             <div class="rowDiv">  
  36.                 <div ng-view>  
  37.                 </div>  
  38.             </div>  
  39.         </div>  
  40.     </div>  
  41. </body>  
  42. </html>  
For the Require js files, we can download the file from nuget package.
 
IndexController.Js
  1. testApp.controller('IndexController', ['$http''$window''$location'function ($http, $window, $location) {  
  2.     var self = this;  
  3.   
  4.     self.message = 'Single Page Application';  
  5.   
  6.     self.pageChanage = function (key) {  
  7.         switch (key) {  
  8.             case 1:  
  9.                 $location.path("/P1");  
  10.                 break;  
  11.             case 2:  
  12.                 $location.path("/P2");  
  13.                 break;  
  14.             case 3:  
  15.                 $location.path("/P3");  
  16.                 break;  
  17.             default:  
  18.                 $location.path("/home");  
  19.                 break;  
  20.         }  
  21.     }  
  22. }]);  
Home.html
  1. <div>  
  2.     Home Page  
  3. </div>  
Page1.html
  1. <div>  
  2.     {{model.message}}  
  3. </div>  
Page1.js
  1. testApp.register.controller('PageController1', ['$http'function ($http) {  
  2.     var self = this;  
  3.   
  4.     self.message = 'Page 1';  
  5. }]);  
Page2.html
  1. <div>  
  2.     {{model.message}}  
  3. </div>  
Page2.Js
  1. testApp.register.controller('PageController2', ['$http'function ($http) {  
  2.     var self = this;  
  3.   
  4.     self.message = 'Page 2';  
  5. }]);  
Page3.html
  1. <div>  
  2.     {{model.message}}  
  3. </div>  
 Page3.js
  1. testApp.register.controller('PageController3', ['$http'function ($http) {  
  2.     var self = this;  
  3.   
  4.     self.message = 'Page 3';  
  5. }]);  
Now run the project and output will be like the following:
 

Read more articles on RequireJS: