我们在使用懒加载的情况下,在系统开始加载的时候,只加载首页,剩余的模块在使用时才进行加载,如果新加载模块非常庞大,那么经常会出现这种情况:在第一次点击新添加的模块的时候,相应的模块会出现卡顿的情况。再次点击此模块的时候,不会出现这种情况。为了解决模块首次加载会出现卡顿的情况,Angular提供了预加载策略
来解决这个问题。预加载
是在懒加载
的基础上进行的。
RouterModule.forRoo()
的第二个参数
可以添加配置选项,配置选项中就有一个是preloadingStrategy
配置,这个配置是一个预加载策略配置。
Angular中提供了两种加载策略,一种是上面用到PreloadAllModules
,还有一种是NoPreloading
,也就是没有预加载,源码注释说明了默认的模式是NoPreloading
这个PreloadAllModules
策略来自@angular/router
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { routes } from './main.routing';
import { RouterModule } from '@angular/router';
import { PreloadAllModules } from '@angular/router';
@NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
使用PreloadAllModules的缺点是不能控制那些模块加载那些模块不加载,我们可以定义自己的预加载策略,并在模块中使用
新建一个selective-preloading-strategy.ts的文件,使用class实现PreloadingStrategy接口的preload方法,代码如下:
import { PreloadingStrategy, Route } from "@angular/router";
import { Observable } from "rxjs";
/**
* 预加载策略
*/
export class SelectivePreloadingStrategy implements PreloadingStrategy {
preload(route: Route, load: Function): Observable {
//当路由中配置data: {preload: true}时预加载
return route.data && route.data && route.data['preload'] ? load() : Observable.of(null);
}
在routing-module.ts 使用 data: {preload: true}
import { Routes } from '@angular/router';
// HomeComponent this components will be eager loaded
import { HomeComponent } from './home/home.component';
export const routes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'shop', loadChildren: './shop/shop.module#ShopModule', data: {preload: true} },
{ path: '**', component: HomeComponent }
];
在 app.module.ts 中使用这个策略,需要注意的是,您还需要在prodivers
中添加这个类。以实现依赖注入。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { routes } from './main.routing';
import { RouterModule } from '@angular/router';
import { PreloadSelectedModules } from './preload.module';
@NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(routes, { preloadingStrategy: PreloadSelectedModules })
],
providers: [PreloadSelectedModules ],
bootstrap: [AppComponent]
})
export class AppModule { }
实现接口 PreloadingStrategy
,我们定义一个 CustomPreloadingStrategy 的自定义策略类。
import { Route } from '@angular/router';
import { PreloadingStrategy } from '@angular/router';
import { Observable } from 'rxjs/Rx';
export class CustomPreloadingStrategy implements PreloadingStrategy {
preload(route: Route, fn: () => Observable): Observable {
return Observable.of(true).delay(5000).flatMap((_: boolean) => fn());
}
}
修改 app.module.ts 使用这个自定义策略。需要注意的是,您还需要在prodivers
中添加这个类。以实现依赖注入。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { routes } from './main.routing';
import { RouterModule } from '@angular/router';
import { CustomPreloadingStrategy } from './preload';
@NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(routes, { preloadingStrategy: CustomPreloadingStrategy })
],
providers: [CustomPreloadingStrategy ],
bootstrap: [AppComponent]
})
export class AppModule { }
参考:
https://blog.csdn.net/happykala/article/details/77945000
https://blog.csdn.net/rotating_windmill/article/details/75142648
https://www.cnblogs.com/haogj/p/7649707.html