【angular5】浅谈serviceWorker与angular5——(1)

前言

本文记录在angular5的项目中添加serviceWorker时遇到问题以及代码解析。

文章提纲:

  • serviceWorker介绍
  • 如何在angular5项目中添加serviceWorker
  • serviceWorker代码解析
  • 遇到的问题

serviceWorker是什么?

  serviceWorker是浏览器在后台独立于网页运行的一段脚本。他通过域名标识不同的网页。网页通过注册自己的serviceWorker,可以将一些相对独立的任务丢到serviceWorker里面运行,并最终通过postMessage进行通信。

  1)生命周期

  一个serviceWorker的的生命周期经历四个步骤:installing,installed,activating,activated,redundant。

  installing:标志着安装的开始,在这个过程中设置离线缓存的config。

  installed:已经安装完毕,等待其他的service worker线程关闭。

  activated:激活态,表明该service worker开始正式工作。

  activating:如果ngsw-worker.js执行出现了错误,则会进入激活失败的状态。

  redundant:如果不想要这个service worker了,可以unregister, 或者stop,这个时候就会进入废弃状态。

  2)事件

   有三个重要的功能性事件,fetch,push,sync。

   fetch:hook主页面全部的网络请求。

   push:如果订阅了后台推送事件,可以使用推送方式唤醒 Service Worker 以响应来自系统消息传递服务的消息,即使用户已经关闭了页面。

   sync:sync 事件由 background sync (后台同步)发出。background sync 配合 Service Worker 推出的 API,用于为 Service Worker 提供一个可以实现注册和监听同步处理的方法(还没用过)。

如何在angualr5中使用service worker?  

 angular5提供了一个serviceWorker模块。我们只要定义好缓存的规则,就可以轻松的使用service worker了~

 材料准备:与当前angular版本匹配的service worker版本。这里需要注意版本一定要相对应,否则会发生activate但不可用的情况。本地"@angular/service-worker": "^5.2.0"。

npm i @angular/service-worker

 修改angular-cli.json

"app": {
"serviceWorker": true,
}

 引入service-worker:

 在app.moudule.ts中引入service-worker。需要注意service-worker需要工作在production环境。所以引入方式如下:

imports: [        
    BrowserModule,   
    environment.production ? ServiceWorkerModule.register('/ngsw-worker.js') : [], 
]

  其中register的路径在相对于cdn静态资源的位置而言。当app.moudule运行在该位置的时候,需要ngZone处在stable的状态,否则不会注册seviceWorker。因此为了防止这种情况,采用手动注册的方法。如:

platformBrowserDynamic().bootstrapModule(AppModule).then(()=>{
    if(navigation.serviceWorker && !navigation.serviceWorker.controller){
        navigation.serviceWorker.register('/ngsw-worker.js');
    }
})
  .catch(err => console.log(err));

  接着需要为serviceWorker准备config.json,指定哪些静态资源,哪些api对应的数据,需要缓存,以及遵循的缓存策略。在src目录下创建文件ngsw-config.json.

{
 "index": "/index.html",
 "assetGroups": [{
  "name": "app",
  "installMode": "prefetch",
  "resources": {
   "files": [
    "/favicon.ico",
    "/index.html"
   ],
   "versionedFiles": [
    "/*.bundle.css",
    "/*.bundle.js",
    "/*.chunk.js"
   ]
  }
 }, {
  "name": "assets",
  "installMode": "lazy",
  "updateMode": "prefetch",
  "resources": {
   "files": [
    "/assets/**"
   ]
  }
 }],
 "dataGroups": [
    {
      "name": "public-url",
      "urls": ["/users/", "loginV2"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize":100,
        "timeout": "1s"
      }
    },{
      "name": "public-cache-url",
      "urls": ["/tags", "/nation"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize":100,
        "maxAge": "10d",
        "timeout": "1s"
      }
    }
]
}

index: 指定根页面文件,一般是index.html

assetsGroup: 缓存的静态文件,一般为页面需要的js,css。assets文件下一般存有文件需要的静态资源,也可以设置缓存。

dataGroup:对应api获取的数据,所采取的缓存策略。

service-worker提供两种缓存策略:

  • lazy模式:在需要的时候缓存,当该资源被请求的时候,才缓存它。
  • prefetch:标明该资源对于app很重要,在install的时候,就提前请求并保存下来。

 可以在两种事件中应用以上两种缓存策略,一个是installMode,一个是updateMode。

  • installMode: 当serviceWorker第一次注册,并且第一次设置缓存的时候。
  • updateMode: 当assetsgroup有新版本的时候。

 dataGroup也应用同样的缓存策略。写法与assetsGroup略有不同。

 urls:指定应用该策略的的url规则。

 cacheConfig:指定urls下的缓存规则:

  •  strategy:缓存规则,分为fressness 和performance两种。fressness表示先从网络拉去数据,如果获取失败,则应用本地缓存。performance标明优先使用本地缓存,如果失败,再从网络获取。
  • maxSize:表明该规则下最多能缓存多少条数据
  • maxAge:表明缓存的有效存续事件
  • timeout:指应用某种类数据,到获取失败使用备用数据,中间的等待事件。例如:如果是fressness,timeout=1s,表示先从网络获取数据,如果1s内还没有得到数据,则使用缓存。

 当写好自己的service-worker的时候,运行命令,

ng build --prod

  文件打包完之后,可以在dist目录下,看到angularWorkerModule生成的ngsw-worker.js和ngsw-config.json。

  启动服务,打开开发者工具applicaiton service-worker,即可发现脚本注册在指定域名下了。这里需要注意的是service-worker需要运行在https上,所以本地域名必须支持https。

  

 运行一段事件之后,断开网络再访问该页面,发现可以无障碍的使用已经加载过的页面(如果没有新数据的产生)。

 ngsw-worker.js到底做了什么?

 到此service-worker已经可以使用了。不过我们还想看看service-worker的缓存到底是如何实现的。以下分析下ngsw-worker.js的内容。

 内容太多。。。另起一篇。

猜你喜欢

转载自blog.csdn.net/u013237862/article/details/82389966