Angular懒加载服务工作者预取

5

我意识到使用懒加载如果用户没有访问页面,则会丢失PWA的主要特性,即您无法离线浏览。

那么有没有一种方法可以预取懒加载文件?

2个回答

6

是的,您需要定义预加载策略:

imports: [RouterModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})]

请查看http://recurship.com/blog/2017/9/30/introduction-to-angular-router-lazy-loading-and-prefetchin以获取更多详细信息。
还可以参考https://blog.cloudboost.io/angular-faster-performance-and-better-user-experience-with-lazy-loading-a4f323b2cf4a 自定义预加载策略:
您还可以使用自定义预加载策略来预加载某些部分而不是其他部分。
请参见https://blog.cloudboost.io/angular-faster-performance-and-better-user-experience-with-lazy-loading-a4f323b2cf4a#e836
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class CustomPreloadingStrategy implements PreloadingStrategy {
  preloadedModules: string[] = [];

  preload(route: Route, load: () => Observable<any>): Observable<any> {
    if (route.data && route.data['preload']) { // see app.routing.ts
      this.preloadedModules.push(route.path);
      return load();
    } else {
      return Observable.of(null);
    }
  }
}

接着在app.module.ts文件中:

@NgModule({
  imports: [RouterModule.forRoot(routes, { preloadingStrategy: 
CustomPreloadingStrategy })],
  exports: [RouterModule],
  providers: [CustomPreloadingStrategy]
})

app.routing.ts:

{
    path: ':section',
    loadChildren: './gm-email/gm-email.module#GmEmailModule',
    data: { preload: true }
}

基本上,如果数据预加载(data.preload)为真,则表示在应用程序已加载后立即预加载此项(即在第一个模块惰性加载后)。否则,在需要时进行预加载(即当用户单击链接进行惰性加载时)。


谢谢回复,但是使用PreloadAllModules会失去惰性加载的好处,我错了吗? - Whisher
1
我从未尝试过,但我认为它会在惰性加载初始模块之后开始预加载,否则预加载就没有意义 - 另外,您可以定义自定义预加载策略。 - danday74
对于这种情况,Angular 提供了一种方法来告诉路由器在应用程序加载后立即异步加载所有惰性加载模块,而不是等待用户单击以激活模块。 - danday74
感谢您提供详尽的回答,但我只知道自定义预加载器,我在我的应用程序中有相同的代码。1)“路由器在应用程序加载后立即异步加载所有惰性加载模块”,您确定吗?我从未见过这样的情况。2)另一个问题是我将所有应用程序都设置为惰性加载,因此在app.routing中,我只有主要路由(我的功能主页auth admin),使用forRoot,然后在每个模块中使用forChild进行其他的惰性加载,例如对于admin帖子媒体用户的'partials'。因此,我不确定是否仍在使用PreloadAllModules时,子模块是否正在加载。 - Whisher
如果您点击模块,它应该更快地加载。此外,在网络选项卡中不应有任何资源请求,除了HTTP API请求。显然,这假设在您点击应用程序时预加载已完成。 - danday74
显示剩余3条评论

1
在Angular服务工作者文件ngsw-config.json中,将installMode设置为prefetch,并在resources.files数组中指定/*.js,这将指示Angular服务工作者在PWA安装时预取您的惰性加载.js包,在用户在线浏览器导航时不会失去惰性加载的好处。
示例:
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/manifest.webmanifest",
          "/*.css",
          "/*.js"
        ]
      }
    }
  ]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接