预加载是介于直接加载、惰加载的一种方式。
预加载的工作原理
在每次成功的导航后,路由器会在自己的配置中查找尚未加载并且可以预加载的模块。 是否加载某个模块,以及要加载哪些模块,取决于预加载策略。
Router
内置了两种预加载策略:
-
完全不预加载,这是默认值。惰性加载的特性区仍然会按需加载。
-
预加载所有惰性加载的特性区。
PreloadAllModules
默认情况下,路由器或者完全不预加载或者预加载每个惰性加载模块。 路由器还支持自定义预加载策略,以便完全控制要预加载哪些模块以及何时加载。
CanLoad会阻塞预加载
PreloadAllModules
策略不会加载被CanLoad守卫所保护的特性区。这是刻意设计的。
CanLoad
守卫的优先级高于预加载策略。如果我们要加载一个模块并且保护它防止未授权访问,请移除canLoad
守卫,只单独依赖CanActivate守卫。
预加载所有惰性模块
要为所有惰性加载模块启用预加载功能,请从Angular的路由模块中导入PreloadAllModules
。
RouterModule.forRoot
方法的第二个参数接受一个附加配置选项对象。 preloadingStrategy
就是其中之一。 把PreloadAllModules
添加到forRoot
调用中。
RouterModule.forRoot(
appRoutes,
{
enableTracing: true, // <-- debugging purposes only
preloadingStrategy: PreloadAllModules
}
)
自定义预加载策略
使用自定义预加载策略,我们可以控制路由器预加载哪些路由以及如何加载。
在这一节,我们将添加一个自定义策略,它只预加载那些data.preload
标志为true
的路由。我们可以往路由的data
属性中添加任何东西。
基本做法就是自定义预加载策略,然后在preloadingStrategy项中使用该策略
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class SelectivePreloadingStrategy implements PreloadingStrategy {
preloadedModules: string[] = [];
preload(route: Route, load: () => Observable<any>): Observable<any> {
if (route.data && route.data['preload']) {
// add the route path to the preloaded module array
this.preloadedModules.push(route.path);
// log the route path to the console
console.log('Preloaded: ' + route.path);
return load();
} else {
return Observable.of(null);
}
}
}