AngularJS supports multi-view applications through routing, and can dynamically load the required views based on routing. This is described in detail in the AngularJS documentation, and there are many tutorials on the Internet, so no need to introduce it!
As the number of views continues to increase, there will be more and more js files, and AngularJS needs to load all js at once by default, which is very inconvenient to use. Therefore, the demand for loading modules on demand will become stronger and stronger. However, , AngularJS does not implement on-demand loading.
I am used to the asynchronous loading method of seajs, and I also thought that angular can also use asynchronous loading, but the fact is not what I want.
Angularjs, like requirejs, uses a preloading method to organize modules (which is exactly the opposite of lazy loading of seajs). When there are more and more modules in a single page application, it means that the modules that need to be preloaded also increase. There will be more and more, which may also show that angular is more suitable for developing light applications.
Officially begins
I used angular-ui-router for routing, and the module loader is requirejs
//路由 { state : 'login', templateUrl : 'login/login.html', controller : 'loginCtrl', resolve: { realCtrl : function ($q) { var def = $q.defer(); require(['/features/login/login.js'], function (loginCtrl) { def.resolve(loginCtrl) }); return def.promise; } } }, // 获得$controllerProvider app.config(function($controllerProvider) { app.registerController = $controllerProvider.register; // ... }) // loginControler app.registerController('loginCtrl', function ($scope) { // do something });
How to implement on-demand loading for angular applications
We have a system developed using Angular, which is a single-page application. With the iteration of the system, the first screen code has become too large, so the system needs to be transformed.
We mainly face 3 problems
1. Is a module loading framework required?
2. How to register the page components loaded asynchronously?
3. When should page components be loaded?
Regarding the first question, since Angular itself already has a set of modular solutions, introducing a module loading framework is a bit redundant, and the overall transformation amount is relatively large, so it is not considered.
So just implement a loadscript method to load components. A little attention needs to be paid to the serial and parallel loading of multiple files, and to avoid repeated loading when the page is repeatedly switched.
The second question is more annoying. Angular has a term for "startup". "Startup" occurs after domcontentloaded, and all dependencies injected into the main module will be compiled.
After starting, if you want to use the controller, deractive and other APIs, an error will be reported directly
Currently, there is only one way to solve this problem, which is to use the provider of the main module to actively register the controller. However, since the provider cannot be used directly, we store it under the main module.
The saved method can be used to register asynchronously loaded page components. The disadvantage is that all subpages are hung under the main module.
Regarding the third question, since the operating platform is a single-page application, the best loading time should be when the routing monitors the hash change. However, since our routing is a hard-coded static configuration, we did not find any good solution at the beginning.
Later I discovered such an API
Probably, we can do something before $routeChangeSuccess, and it is most suitable to put the loading time here
The specific implementation is probably like this
At this point, the plan has been approved, what work is left?
1. Organize the code to make it more general. When we develop new pages in the future, we only need to write this in the routing configuration
2. Transform all existing pages. Since there was no on-demand loading before, the service coupling between different pages is serious. In the future, when we develop new pages, we must pay attention to the fact that services shared between different pages are best placed in components. Below
3. Change the build and replace the js reference in the route with the cdn path.