- 使用懶載入才會存在預載入的概念
- 預載入是自己載入完了再去載入其他模組
- 注意,是自己載入完也就是閒時再去載入
預載入指定模組
參考了很多例子,雖然實現了預載入但卻是在本模組內容沒載入完就會去載入延遲模組,這樣就等於沒有配置懶載入,所以得進行一些優化。
1. 雖然配置了預載入但卻在本模組沒載入完就去載入延遲模組了(bad)
├─app.module.ts
├─app.routes.ts
├─shared
└─service
└─preview-load.ts
preview-load.ts
import { Observable } from 'rxjs/Rx';
import { PreloadingStrategy, Route } from '@angular/router';
export class PreloadModules implements PreloadingStrategy {
preload(route: Route, load: Function): Observable<any> {
return route.data && route.data.preload ? load() : Observable.of(null);
}
}
複製程式碼
app.module.ts
import { ROUTER_CONFIG } from './app.routes';
import { PreloadModules } from './share/service/preview-load';
...
@NgModule({
imports: [
RouterModule.forRoot(ROUTER_CONFIG, {preloadingStrategy: PreloadModules} )
],
providers: [
PreloadModules
],
複製程式碼
app.routes.ts
...
export const ROUTER_CONFIG: Routes = [
...
{
path: 'login',
component: RoleLoginComponent
},
{
path: 'lists',
loadChildren: './tables/tables.module#TablesModule',
data: { preload: true }
}
];
複製程式碼
實測:
- 在250ms的時候頁面沒有渲染好並且沒有載入延遲載入的table模組
- 在2.55s的時候檔案載入完成並開始渲染頁面,這時候已經載入了table模組的js了,這就違背了預先載入延遲模組的初衷了。所以得治~
2. 閒時再載入延遲模組(good)
部分檔案、結構和上面一樣,只對preview-load.ts檔案做一些更改
import { Observable } from 'rxjs/Rx';
import { PreloadingStrategy, Route } from '@angular/router';
import { Injectable, NgZone } from '@angular/core';
export function requestIdle(zone: NgZone) {
const win: any = window;
if (win.requestIdleCallback) {
return (fn) => win.requestIdleCallback(fn);
}
return (fn) => zone.runOutsideAngular(() => win.setTimeout(fn, 10));
}
@Injectable()
export class PreloadModules implements PreloadingStrategy {
constructor(
private zone: NgZone
) { }
preload(route: Route, fn: () => Observable<any>): Observable<any> {
requestIdle(this.zone)(fn);
return Observable.of(null);
}
}
複製程式碼
看結果
- 在2.92s的時候頁面渲染完成那一刻還是沒有載入table模組
- 在所有載入完之後開始載入table模組
如果覺得文章不錯,不妨點個贊。
首發於github。