• 异步路由的预加载示例: 为了尽可能减小初始加载体积和最快的加载速度,让 主模块和A模块 先加载;如何懒加载其他模块,但是B 模块可能是 用户在打开应用后,几分钟或几秒钟就会访问的模块;(比如打开微信后,是不是进入主页面;然后是不是要打开朋友圈瞅瞅;而B模块就相当于朋友圈功能;)所以,这个时候在用户打开B模块前;该模块就已经预加载完毕可供访问;
  • 预加载原理:
  •   每次成功导航后,路由器会在自己的配置中查找尚未加载并且可以预加载的模块
  • 预加载策略:
  •   默认 都不预加载,懒加载的模块仍会按需加载
  • 预加载所有懒加载模块
  • 自定义预加载
  • 用户场景:将CrisisCenterModule 改为默认懒加载,并使用全部预加载策略来加载所有懒加载模块
  1. 对crisis-center 模块进行懒加载处理
// crisis-center-routing.ts 该路径为空路径
const crisisCenterRoutes: Routes = [
  {
    path: '', component: CrisisCenterComponent, children: [
      { path: '', component: CrisisListComponent, children: [
        // tslint:disable-next-line: max-line-length
        { path: ':id', component: CrisisDetailComponent, canDeactivate: [CanDeactivateGuard], resolve: { crisis: CrisisDetailResolverService }},
        { path: '', component: CrisisCenterHomeComponent}
      ]}
    ]
  }
];

// AppRoutingModule  增加该模块路由,并设置loadChildren
const appRoutes: Routes = [
  {
    path: 'compose',
    component: ComposeMessageComponent,
    outlet: 'popup'
  },
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(mod => mod.AdminModule),
    canLoad: [AuthGuard]
  },
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis-center/crisis-center.module').then(mod => mod.CrisisCenterModule),
    data: { preload: true } // 自定义预加载
  },
  { path: '', redirectTo: '/superheroes', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

// AppModule 中 移除该模块
import { HeroesModule } from './heroes/heroes.module';
// import { CrisisCenterModule } from './crisis-center/crisis-center.module';
// import { AdminModule} from './admin/admin.module';
import { AuthModule} from './auth/auth.module';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // 导入动画模块


import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { ComposeMessageComponent } from './compose-message/compose-message.component';



@NgModule({
  declarations: [
    AppComponent,
    PageNotFoundComponent,
    ComposeMessageComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HeroesModule,
    // CrisisCenterModule,
    // AdminModule,
    AuthModule,
    AppRoutingModule,
    BrowserAnimationsModule
  ],
  1. 为所有懒加载模块启动预加载功能,在AppRoutingModule 中导入PreloadAllModules 
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';

import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { AuthGuard } from './auth/auth.guard';

const appRoutes: Routes = [
  {
    path: 'compose',
    component: ComposeMessageComponent,
    outlet: 'popup'
  },
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(mod => mod.AdminModule),
    canLoad: [AuthGuard] //CanLoad 会阻塞预加载,该优先级高于预加载策略
  },
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis-center/crisis-center.module').then(mod => mod.CrisisCenterModule),
    data: { preload: true }
  },
  { path: '', redirectTo: '/superheroes', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes,
      {
        enableTracing: false,
        preloadingStrategy: PreloadAllModules, //让所有(带loadChildren属性的路由)懒加载模块立即预加载
      }
    )
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }
  1. 关于自定义预加载;这里自定义策略为:只预加载data.preload 为 true  的路由;
  2. 生成自定义服务
ng generate service selective-preloading-strategy

import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class SelectivePreloadingStrategyService implements PreloadingStrategy {
  preloadedModules: string[] = [];
// 参数 route -- 要加载的路由 load() -- 加载器函数,异步加载带路由的模块
// 如果该路由应该预加载,就会跳用load()函数返回Observable对象,否则返回null; 
  preload(route: Route, load: () => Observable<any>): Observable<any> {
    if (route.data && route.data['preload']) {
      this.preloadedModules.push(route.path); //会将所选路由记录在数组中;
      console.log('Preloaded: ' + route.path);
      return load();
    } else {
      return of(null);
    }
  }
}
  1. 自定义预加载处理
// AppRoutingModule
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';

import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { AuthGuard } from './auth/auth.guard';
import { SelectivePreloadingStrategyService } from './selective-preloading-strategy.service';

const appRoutes: Routes = [
  {
    path: 'compose',
    component: ComposeMessageComponent,
    outlet: 'popup'
  },
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(mod => mod.AdminModule),
    canLoad: [AuthGuard]
  },
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis-center/crisis-center.module').then(mod => mod.CrisisCenterModule),
    data: { preload: true }
  },
  { path: '', redirectTo: '/superheroes', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes,
      {
        enableTracing: false,
        preloadingStrategy: SelectivePreloadingStrategyService,
      }
    )
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }
  1. 编辑adminDashboardComponent 来显示预加载路由日志, 当加载完初始路由后,crisisCenterModule被预加载,通过该模块可以在控制台看到日志
// html
<p>Dashboard</p>

<p>Session ID: {{ sessionId | async }}</p>
<a id="anchor"></a>
<p>Token: {{ token | async }}</p>

Preloaded Modules
<ul>
  <li *ngFor="let module of modules">{{ module }}</li>
</ul>

// ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { SelectivePreloadingStrategyService } from '../../selective-preloading-strategy.service';

@Component({
  selector: 'app-admin-dashboard',
  templateUrl: './admin-dashboard.component.html',
  styleUrls: ['./admin-dashboard.component.css']
})
export class AdminDashboardComponent implements OnInit {
  sessionId: Observable<string>;
  token: Observable<string>;
  modules: string[];

  constructor(
    private route: ActivatedRoute,
    preloadStrategy: SelectivePreloadingStrategyService
  ) {
    this.modules = preloadStrategy.preloadedModules;
  }

  ngOnInit() {

    this.sessionId = this.route
      .queryParamMap
      .pipe(map(params => params.get('session_id') || 'None'));

    this.token = this.route
      .fragment
      .pipe(map(fragment => fragment || 'None'));
  }
}

angular karma 升级 jest angular预加载_加载

 

想买的东西很贵,想去的地方很远,喜欢的女孩很完美