Late registering
&
Lazy loading
Gonzalo Ruiz de Villa Suárez
@gruizdevilla
@gruizdevilla
Demo project
You may find the sources at:
https://github.com/gonzaloruizdevilla/angularlazyload
To start the project:
$ npm install
$ bower install
$ npm start
and open http://localhost:3000/
By default,
AngularJS does not allow the registry of new resources after the app starts:
However, you may access the pieces that can register resources in the config phase.
If you expose them, in a somehow artificial way, you may use then later to register new resources.
Exposing these utilities for later registering of resources
module.config(
function (
$controllerProvider,
$compileProvider,
$filterProvider,
$provide
) {
module.lazy = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
}
);
You may register new resources after the app has started:
module.lazy.factory('MySrv', function () {
//factory body
});
However, unit tests can get a little more complicated. You can prevent this if you register services this way:
(module.lazy || module).factory('MySrv', function () {
//factory body
});
When unit testing, karma loads all scripts before starting, therefore registering all the resources before starting the app.
Even better doing this:
module.config(
function (
$controllerProvider,
$compileProvider,
$filterProvider,
$provide
) {
module.controller = $controllerProvider.register;
module.directive = $compileProvider.directive;
module.filter = $filterProvider.register;
module.factory = $provide.factory;
module.service = $provide.service;
}
);
In the config phase, we replaces methods that become useless with the new ones that allows late registering. The app then is completely unchanged, even when adding this feature afterwards in the project development.
Limitations
- No official support for these techniques. No guarantee that they will be compatible with next versions of AngularJS 1.*.
- As the config phase ended and the app is already running, then:
- You can't configure the new loaded resources. Therefore, it has no sense to register lately with the 'provider' method.
- You can't decorate the new resources.
- You can't add new modules.
However, in my experience, these limitations weren't important for the resources I wanted to register lazily.
Lazy loading
It is very important to find the best fitting convention for your project: it will minimize the configuration needed for lazy loading.
Tip: rely on the route configurations. Add in the '
resolve
' property a function that returns a promise that will be resolved then the dependencies are loaded.Script.js
Por the example, I use script.js, a very lightweight (1.5kb) library for async loading of scripts
bower install script.js --save
https://github.com/ded/script.js
To prepare the route's configuration:
function resolveDependencies(config, dependencies) {
config.resolve = {
dependencies: function ($q, $rootScope) {
var deferred = $q.defer();
$script(dependencies, function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}
};
}
Using RequireJS
The same principle, but a little more complex
and powerful due to AMD
and RequireJS nature:
and powerful due to AMD
and RequireJS nature:
- Pasa la referencia al módulo de AngularJS
mediante los mecanismos de RequireJS - The AngularJS app must be started manually
(app.bootstrap), because it is RequireJS
who knows when the resources have finished
loading.
To RequireJS or not to RequireJS
- RequireJS is much much more powerful,
but it adds complexity you need to take into account: - Configuration: dependencies are defined twice in each file: inside 'define' and when registering the resource in AngularJS. Without RequireJS, you may have this duplicity too (as in the example), but you can remove all or part of it with conventions.
- Testing is more complex with RequireJS. With the first technique, testing is done as usual.
¡Thanks!
Late registering and lazy load in AngularJS (en)
By Gonzalo Ruiz de Villa
Late registering and lazy load in AngularJS (en)
Late registering and lazy load in AngularJS
- 9,356