Lazy loading components in angular using a browser

I am in the process of expounding the architecture of a rather complex angular-based application. So I started with the angular -seed project, and it seems like a good starting point. My concern is that angular applications, by their nature, include downloading everything in advance. With script loaders, there seems to be no clean way.

I came from the backbone.js background, and it was quiet right there to use require.js for lazy loading based on router callbacks. In angular routes, it is somewhat defined as follows:

// Declare app level module which depends on views, and components angular.module('myApp', [ 'ngRoute' ]). config(['$routeProvider', function($routeProvider) { $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) .when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) .otherwise({redirectTo: '/view1'}); }]); 

now here, $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) I would like to lazily load the controller and the template. I was tempted to use something like:

 $routeProvider.when({templateURL:'../tmpl.html',controller:require('view1Ctrl'}) 

using a browser, but then it does not seem clean and does not even require. I know this question has been asked several times on SO anyway, but I have not found a decisive answer to this.

My advantage here is the use of a browser, as it supports the very favorite cjs modules in the browser.

+5
source share
1 answer

I am not sure how to do this with Browserify, as I have never tried this myself, but I highly recommend that you take a look at ocLazyLoad .

As a standalone service, it works with download files (json, css, js, templates - you name it) and enter them into an already running angular application.

With this in mind, it works even better (imo) in combination with a router (default is angular one or ui-router).

There are several “seed projects" that demonstrate how this can be done with ocLazyLoad in conjunction with SystemJS.


But you don’t even need it.

If you go with ui-router, ui-router-extras and ocLazyLoad, you can add something like this to the lazy load states:

main.js

 /** * Inject the needed dependencies into our main module. */ var main = angular.module('main', [ 'ui.router', 'ct.ui.router.extras.future', 'oc.lazyLoad' ]); /** * Define the lazy loaded states. */ main.constant('lazyLoadedStates', [ { name: 'about', url: '/about', type: 'lazy', src: [ '/path/to/about.module.js', '/path/to/AboutController.js' ] } ]); /** * Setup the behaviour for when we hit a futureState with the 'lazy' * type. * * 1. Setup a deferred object. * 2. Resolve the promise when every file defined in the futureState.src has been loaded. * 3. Return the promise. */ main.config(function ($futureStateProvider, lazyLoadedStates) { $futureStateProvider.stateFactory('lazy', function ($q, $ocLazyLoad, futureState) { var deferred = $q.defer(); $ocLazyLoad.load(futureState.src).then(function () { deferred.resolve(); }); return deferred.promise; }); lazyLoadedStates.forEach($futureStateProvider.futureState); }); 

With the "framework" aside - now you just need to add additional modules, with a lot of code, and map the real state definition to the dummy in the constant lazyLoadedStates .

about.module.js

 /** * Setup the _real_ '/about' state in this lazy loaded file. */ angular.module('about', []).config(function ($stateProvider) { $stateProvider.state('about', { url: '/about', controller: 'AboutController', template: 'some_template.html' }); }); 

AboutController.js

 /** * Register the AboutController in a lazy loaded file. This could be done in about.module.js aswell, * but we'll do it here to separate stuff and showcase loading of multiple files. */ angular.module('about').controller('AboutController', function ($state) { console.log('Im on a lazy loaded state!', $state.current); }); 

Hope this gives you a general idea on how to set up lazy loaded states in Angular. I have yet to find an easier way to do this, but I'm sure there are articles on how to associate ui-router (or the default angular router) with some other “lazy bootloader”.

Doc Links:

+3
source

All Articles