angular+ 路由學習 (九)異步路由都預加載


  • 異步路由的預加載示例: 為了盡可能減小初始加載體積和最快的加載速度,讓 主模塊和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
      ],

     

  2. 為所有懶加載模塊啟動預加載功能,在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 { }

     

  3. 關於自定義預加載;這里自定義策略為:只預加載data.preload 為 true  的路由;
  4. 生成自定義服務
    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);
        }
      }
    }

     

  5. 自定義預加載處理
    // 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 { }

     

  6. 編輯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'));
      }
    }

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM