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

之后:

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: [email protected]
@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

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: [email protected]
@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<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 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: [email protected]
@file: app-routing.module.ts
@time: 2018 / 7 / 2 17: 18

*/

使用

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 } }, // 懒加载 + 预加载

];

猜你喜欢

转载自blog.csdn.net/xif3681/article/details/84584317
今日推荐