复杂的 AngularJS SPA 项目需要用路由来管理各个产品模块之间的切换。各个模块的代码如何引入?通常我们的简单做法是在首页将各个模块的代码全部引入,即使首页本身很简单也需要加载很多无用的代码。这样 一来会造成首屏加载时间过长。怎么做到首屏只引入需要显示的必要代码,而在必要的时候再去加载各个模块的代码,做到按需懒加载呢?
可能最容易想到的是使用 RequireJS,网上也有这样的方案介绍,甚至有一些脚手架工程供我们使用。不过 RequireJS 的侵入式代码恐怕不是每个人都很接受的,万一哪天使用改成 CMD、XMD 又不得不改动代码,使用 RequireJS 只能算可行方案。有没有更好的方案呢?试一试 ocLazyLoad,目前已经是 1.0 版本,比较稳定了。
ocLazyLoad 快速入门
- 下载 ocLazyLoad.js。可以在
git
存储库的dist
文件夹中找到该文件,也可以通过bower install oclazyload
或npm install oclazyload
来安装。 - 将
oclazyLoad
模块添加到应用程序中:
var myApp = angular.module("MyApp", ["oc.lazyLoad"]);
按需加载 :
myApp.controller("MyCtrl", function($ocLazyLoad) { $ocLazyLoad.load('testModule.js'); });
使用 $ocLazyLoad
可以加载 AngularJS 模块, 但如果要加载任何组件(控制器/服务/过滤器/...) 而不用定义新模块也是完全有行的 (只是确保在现有模块中定义了此组件)。
实例
下面的实例使用 angular-ui-router 和 ocLazyLoad 实现了 AngularJS 模块按需懒加载。
- index.html
<body ng-app="mainApp">
<nav>
<ul>
<li><a ui-sref="home" ui-sref-active="active">Home</a></li>
<li><a ui-sref="product" ui-sref-active="active">Product</a></li>
</ul>
</nav>
<ui-view></ui-view>
<script src="app.js"></script>
</body>
- views/product.html
<section>{{text}}</section>
- app.js
angular.module('mainApp', ['ui.router', 'oc.lazyLoad'])
.config(function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('product', {
url: '/product',
templateUrl: 'views/product.html',
controller: 'ProductCtrl',
resolve: {
loadProduct: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load('./js/product.js');
}]
}
})
.state('home', {
url: '/home',
template: '<div>This is the home page</div>'
});
});
- js/product.js
angular.module('productApp', [])
.controller('ProductCtrl', function($scope) {
$scope.text = 'This is Product';
});
- css/style.css
a {
text-decoration: none;
color: #333;
}
a:hover {
color: #900;
text-decoration: underline;
}
a.active {
text-decoration: underline;
}
上述实例中,最关键的步骤是我们设置路由状态对象的 resolve
参数,指定当前 controller 依赖于 $ocLazyLoad.load()
方法动态加载的模块或其它任何组件,这实现了模块按需懒加载。剩下的就是分模块开发了,是不是比 RequireJS 方式更简单友好呢?
评论 (0)