angular 模块懒加载 与 预加载策略

一、模块懒加载
1、RouterModule.forRoot() 和 RouterModule.forChild()
RouterModule对象为提供了两个静态的方法:forRoot()和forChild()来配置路由信息。
RouterModule.forRoot()方法用于在主模块中定义主要的路由信息,RouterModule.forChild()与 Router.forRoot()方法类似,但它只能应用在特性模块中。
即根模块中使用forRoot(),子模块中使用forChild()。
2、懒加载:loadChildren
这里使用到了懒加载LoadChildren属性。这里没有将对应的模块导入到AppModule中,而是通过loadChildren属性,告诉Angular路由依据loadChildren属性配置的路径去加载对应的模块。这就是模块懒加载功能的具体应用,当用户访问 /xxx/** 路径的时候,才会加载对应的模块,这减少了应用启动时加载资源的大小。
loadChildren的属性值由三部分组成:
需要导入模块的相对路径
#分隔符
导出模块类的名称
3、优化: main.bundle.js
之前main.bundle.js的大小为1447KB 减少为 358KB
angular 模块懒加载 与 预加载策略
文章图片

之后:
angular 模块懒加载 与 预加载策略
文章图片

4、实现

( 在项目目录下使用命令行工具)
1.ng g module login --routing
2.ng g component login
app-routing.module.ts

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CanDeactivateGuard } from './guard/can-deactivate-guard.service'; import { SelectivePreloadingStrategy } from './selective-preloading-strategy'; // 预加载 import { PageNotFoundComponent } from './not-found.component'; const appRoutes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full'}, { path: 'login', loadChildren: './login/login.module#LoginModule' }, // 懒加载 { path: 'home', loadChildren: './home/home.module#HomeModule', data: { preload: true } }, // 懒加载 + 预加载 { path: '**', component: PageNotFoundComponent } // 注意要放到最后]; @NgModule({ imports: [ RouterModule.forRoot( appRoutes, { // enableTracing: true, // <-- debugging purposes only preloadingStrategy: SelectivePreloadingStrategy // 预加载} ) ], exports: [ RouterModule ], providers: [ CanDeactivateGuard, SelectivePreloadingStrategy ] }) export class AppRoutingModule { }/*Copyright(c): 2018 深圳创新设计研究院 Author: luo.shuqi@live.com @file: app-routing.module.ts @time: 2018 / 7 / 2 17: 18*/

login-routing.module.ts
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from '../guard/auth-guard.service'; import { AuthService } from '../guard/auth.service'; import { LoginComponent } from './login.component'; const loginRoutes: Routes = [ { path: '', component: LoginComponent } // 注意path: '' ]; @NgModule({ imports: [ RouterModule.forChild(loginRoutes) ], exports: [ RouterModule ], providers: [ AuthGuard, AuthService ] }) export class LoginRoutingModule { }

login.module.ts
angular 模块懒加载 与 预加载策略
文章图片

home-routing.module.ts
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home.component'; import { AuthGuard } from '../guard/auth-guard.service'; const routes: Routes = [{ path: '', component: HomeComponent, canActivate: [AuthGuard], children: [ { path: '', redirectTo: 'homepage', pathMatch: 'full' }, { path: 'homepage', loadChildren: './homepage/homepage.module#HomepageModule', data: { preload: true } }, { path: 'monitor', loadChildren: './monitor/monitor.module#MonitorModule' }, { path: 'device', loadChildren: './device/device.module#DeviceModule' }, { path: 'user', loadChildren: './user/user.module#UserModule' }, { path: 'application', loadChildren: './application/application.module#ApplicationModule' }, { path: 'airreport', loadChildren: './airreport/airreport.module#AirreportModule' }, { path: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule' }, { path: 'led', loadChildren: './led-test/led.module#LedModule' }, { path: 'strategy', loadChildren: './strategy/strategy.module#StrategyModule' }, { path: 'issuedata', loadChildren: './issuedata/issuedata.module#IssuedataModule' }, ] }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class HomeRoutingModule { } /*Copyright(c): 2018 深圳创新设计研究院 Author: luo.shuqi@live.com @file: home.routes.ts @time: 2018 / 7 / 2 17: 18*/

其他routing.module参考上面

二、预加载策略 1、问题描述
在没有使路由懒加载的时候,第一次使用的时候加载特别慢,影响用户体验,angular2可以使用loadChildren进行懒加载,第一次使用的时候只会加载需要的模块,其它模块在真正使用的时候才会去加载,这个时候打开浏览器控制台查看js加载的时候,会发现你在使用时候会去加载对应的js,导致第一次点击相应模块的功能时会卡顿一下,后面在使用就不会了,这样还是用户体验不好,接下来告诉你如果使用预加载策略解决这个问题。
2、预加载策略
RouterModule.forRoot的第二个添加了一个配置选项,这人配置选项中就有一个是preloadingStrategy配置,当然它还有其它配置,这里只讲preloadingStrategy,这个配置是一个预加载策略配置,我们需要实现一个自己的预加载策略,在一些不需要预加载的场景加我们可以不配置,首先新建一个selective-preloading-strategy.ts的文件,使用class实现PreloadingStrategy接口的preload方法,代码如下:
import { Injectable } from '@angular/core'; import { PreloadingStrategy, Route } from '@angular/router'; import { Observable } from 'rxjs'; import { of } from 'rxjs'; @Injectable() export class SelectivePreloadingStrategy implements PreloadingStrategy { preloadedModules: string[] = []; preload(route: Route, load: () => Observable): Observable { 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 of(null); } } }/* Copyright 2017-2018 Google Inc. All Rights Reserved. Use of this source code is governed by an MIT-style license that can be found in the LICENSE file at http://angular.io/license */

导入
app-routing.module.ts
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CanDeactivateGuard } from './guard/can-deactivate-guard.service'; import { SelectivePreloadingStrategy } from './selective-preloading-strategy'; // 预加载 import { PageNotFoundComponent } from './not-found.component'; const appRoutes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full'}, { path: 'login', loadChildren: './login/login.module#LoginModule' }, // 懒加载 { path: 'home', loadChildren: './home/home.module#HomeModule', data: { preload: true } }, // 懒加载 + 预加载 { path: '**', component: PageNotFoundComponent } // 注意要放到最后]; @NgModule({ imports: [ RouterModule.forRoot( appRoutes, { // enableTracing: true, // <-- debugging purposes only preloadingStrategy: SelectivePreloadingStrategy // 预加载} ) ], exports: [ RouterModule ], providers: [ CanDeactivateGuard, SelectivePreloadingStrategy ] }) export class AppRoutingModule { }/*Copyright(c): 2018 深圳创新设计研究院 Author: luo.shuqi@live.com @file: app-routing.module.ts @time: 2018 / 7 / 2 17: 18*/

【angular 模块懒加载 与 预加载策略】
使用
app-routing.module.ts
const appRoutes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full'}, { path: 'login', loadChildren: './login/login.module#LoginModule' }, // 懒加载 { path: 'home', loadChildren: './home/home.module#HomeModule', data: { preload: true } }, // 懒加载 + 预加载];


    推荐阅读