澳门太阳娱乐集团官网-太阳集团太阳娱乐登录

[翻译]入门angular的 Service Workers
分类:网页制作

Service Worker入门

2015/03/26 · JavaScript · Service Worker

初稿出处: Matt Gaunt   译文出处:[w3ctech

  • 十年踪迹]()   

原生App具备Web应用平时所不富有的富离线体验,按时的沉默更新,音讯公告推送等成效。而新的Serviceworkers标准让在Web App上保有那些效能成为或然。

image

原文

Service Worker 是什么?

二个 service worker 是一段运转在浏览器后台进度里的台本,它独立于当下页面,提供了那二个没有须要与web页面交互的法力在网页背后悄悄试行的力量。在前几天,基于它能够完成音信推送,静默更新以及地理围栏等服务,可是当前它首先要具备的功效是阻止和拍卖互连网央求,富含可编制程序的响应缓存管理。

为啥说那些API是二个非常厉害的API呢?因为它使得开采者能够帮忙极度好的离线体验,它赋予开荒者完全调整离线数据的力量。

在service worker提出此前,别的多个提供开荒者离线体验的API叫做App Cache。不过App Cache有个别局限性,举例它能够很轻松地缓和单页应用的难点,不过在多页应用上会很费力,而Serviceworkers的出现正是为了化解App Cache的痛点。

下边详细说一下service worker有怎样供给小心的地方:

  • 它是JavaScript Worker,所以它不能够向来操作DOM。不过service worker能够经过postMessage与页面之间通讯,把音讯通告给页面,若是须要的话,让页面本人去操作DOM。
  • Serviceworker是一个可编制程序的网络代理,允许开拓者调整页面上管理的网络乞请。
  • 在不被使用的时候,它会友善终止,而当它再也被用到的时候,会被再一次激活,所以你无法依据于service worker的onfecth和onmessage的管理函数中的全局状态。借使您想要保存一些悠久化的新闻,你能够在service worker里使用IndexedDB API。
  • 瑟维斯worker多量使用promise,所以一旦你不打听哪些是promise,那您要求先读书这篇文章。

极度简的介

二零一八年初叶火遍南北的 PWA 本领诞生景况有负重望,主要缘于 safrai 对于这一手艺帮助不甚理想,不扶助 mainfest 文件也不扶助 service Worker

service worker 是一个特别的 web Worker,由此她与页面通讯和 worker 是一模二样的,同样无法访问 DOM。特殊在于他是由事件驱动的保有生命周期的 worker,而且能够阻止管理页面的网络伏乞(fetch),能够访问 cacheIndexDB

换言之 service Worker 能够让开拓者本身主宰处理缓存的内容以及版本,为离线弱网遇到下的 web 的运作提供了恐怕,让 web 在感受上极度身入其境 native。

前期准备

如下的基础知识:

  • Angular service workers介绍.

从5angular.0.0开始,在任性cli项目中,你能够很轻易的开启Angular service worker。这文书档案是介绍怎么去在新的或旧的类型中启用Angular service worker。会透过三个轻易的例证是展现service worker的一颦一笑与主导缓存。

Service Worker的生命周期

Service worker具有叁个全然独立于Web页面包车型客车生命周期。

要让一个service worker在你的网址上生效,你需求先在您的网页中登记它。注册八个service worker之后,浏览器会在后台默默运维三个service worker的设置进程。

在设置进程中,浏览器会加载并缓存一些静态能源。假如具有的文本被缓存成功,service worker就设置成功了。假使有任何公文加载或缓存失利,那么安装进程就能够失利,service worker就不能被激活(也即未能安装成功)。假使发生这么的标题,别忧虑,它会在下一次再尝试安装。

当安装完结后,service worker的下一步是激活,在这一品级,你还足以荣升多少个service worker的本子,具体内容我们会在末端讲到。

在激活之后,service worker将接管全体在协调管辖域范围内的页面,不过假设二个页面是刚刚注册了service worker,那么它那贰遍不会被接管,到下叁遍加载页面包车型客车时候,service worker才会生效。

当service worker接管了页面之后,它也许有两种状态:要么被停止以节约内部存款和储蓄器,要么会管理fetch和message事件,这八个事件分别产生于贰个网络央浼现身依旧页面上发送了叁个音讯。

下图是贰个简化了的service worker初次安装的生命周期:

图片 1

合营情状

safrai 已经于 2017年8月 开始了 service Worker 的开发。

image

近期浏览器PC协助情形如图

境内器重浏览器援助意况

android 设备在 4.4 版本选用 Chromium 作为基石,Chromium 在 40 对于 service worker 扶助。国内浏览器包涵微信浏览器在内基本已经协助 service Worker 那为晋级体验提供了也许。service workerHTTP2 尤其配哦,在现在依据它能够完毕音信推送,静默更新以及地理围栏等服务。

在新品类中加多service worker

就算您要生成一个新的cli项目,你能够使用cli去配置Angular service worker:

ng new my-project --service-worker

--service-worker一声令下会去做有所的计划并丰裕需求依附的包。想询问更加多,可查看上边包车型地铁有关什么在旧项目增加service worker的求证

在大家开端写码在此以前

从这个连串地址拿到chaches polyfill。

这个polyfill支持CacheStorate.match,Cache.add和Cache.addAll,而现在Chrome M40实现的Cache API还尚未支持这几个点子。

将dist/serviceworker-cache-polyfill.js放到你的网址中,在service worker中通过importScripts加载进来。被service worker加载的台本文件会被电动缓存。

JavaScript

importScripts('serviceworker-cache-polyfill.js');

1
importScripts('serviceworker-cache-polyfill.js');

需要HTTPS

在开拓阶段,你能够经过localhost使用service worker,可是一旦上线,就需求你的server协理HTTPS。

您能够通过service worker威逼连接,伪造和过滤响应,特别逆天。就算你能够约束自身不干坏事,也许有人想干坏事。所以为了防范旁人使坏,你不得不在HTTPS的网页上注册service workers,那样大家才可避防守加载service worker的时候不被歹徒篡改。(因为service worker权限比非常大,所以要防守它自个儿被人渣篡改利用——译者注)

Github Pages正好是HTTPS的,所以它是三个了不起的先性情实验田。

借使您想要让您的server援助HTTPS,你需求为你的server获得二个TLS证书。分裂的server安装方法不相同,阅读协理文书档案并经过Mozilla’s SSL config generator问询最佳实施。

打探前的摸底

webWorker
fetch
cache
promise

在旧项目中增加service worker

增加步骤:

  1. 增多service worker的包重视。
  2. 在cli配置中启用service worker。
  3. 导入和注册service worker。
  4. 新建配置文件,定义缓存的表现和任何设定。
  5. 编写翻译项目。

使用Service Worker

今昔大家有了polyfill,何况解决了HTTPS,让大家看看见底怎么用service worker。

生命周期

image

Service Workermain.js 举办挂号,第一遍注册前会实行深入分析,判别加载的文书是还是不是在域名下,合同是还是不是为 HTTPS 的,通过这两点则成功注册。
service Worker 开头步向下二个生命周期状态 installinstall 达成后会触发 service Workerinstall 事件。 如果 install 成功则接下去是 activate气象, 然后那些 service worker 技巧接管页面。当事件 active 事件实施到位之后,此时 service Worker 有二种状态,一种是 active,一种是 terminatedactive 是为了职业,terminated则为了省去内部存款和储蓄器。当新的 service Worker 处于 install/waitting 阶段,当前 service Worker 处于 terminated,就能发生交接替换。也许可以由此调用 self.skipWaiting() 方法跳过等待。
被轮换掉的原本的 service WorkerRedundant 阶段,在 install 或者 activating 中断的也会进来 Redundant 阶段。所以七个 Service Worker 脚本的生命周期有如此局地等第(从左往右):

[图形上传战败...(image-af3cfa-1511157771617)]

手续1:加多service worker的包正视。使用yarn包管理工科具:

yarn add @angular/service-worker

何以注册和安装service worker

要设置service worker,你必要在您的页面上登记它。那么些手续告诉浏览器你的service worker脚本在何地。

JavaScript

if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }

1
2
3
4
5
6
7
8
9
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    // Registration was successful
    console.log('ServiceWorker registration successful with scope: ',    registration.scope);
  }).catch(function(err) {
    // registration failed :(
    console.log('ServiceWorker registration failed: ', err);
  });
}

地点的代码检查service worker API是不是可用,假若可用,service worker /sw.js 被注册。

举个例子那几个service worker已经被注册过,浏览器会自行忽略上边的代码。

有二个亟待特别表达的是service worker文件的不二等秘书籍,你早晚留神到了在那个事例中,service worker文件被放在这么些域的根目录下,那意味着service worker和网址同源。换句话说,那么些service work将会接受这一个域下的全部fetch事件。假若笔者将service worker文件注册为/example/sw.js,那么,service worker只能收到/example/路径下的fetch事件(例如: /example/page1/, /example/page2/)。

至今你能够到 chrome://inspect/#service-workers 检查service worker是否对你的网站启用了。

图片 2

当service worker第一版被实现的时候,你也能够在chrome://serviceworker-internals中查看,它很有用,通过它可以最直观地熟悉service worker的生命周期,不过这个功能很快就会被移到chrome://inspect/#service-workers中。

您会开掘这么些意义能够很便利地在一个仿照窗口中测量检验你的service worker,那样您能够关闭和再一次打开它,而不会潜移暗化到您的新窗口。任何成立在模拟窗口中的注册服务和缓存在窗口被关闭时都将一去不复返。

Install

install 存在中间态 installing 这一个情形在 main.jsregistration注册对象中可以访谈到。

/* In main.js */
// 重写 service worker 作用域到 ./
navigator.serviceWorker.register('./sw.js', {scope: './'}).then(function(registration) {  
    if (registration.installing) {
        // Service Worker is Installing
    }
})

安装时 service Workerinstall 事件被触发,那貌似用于拍卖静态财富的缓存

service worker 缓存的静态能源

chrome PWA 演示实例

/* In sw.js */
self.addEventListener('install', function(event) {  
  event.waitUntil(
  // currentCacheName 对应调试工具中高亮位置,缓存的名称
  // 调用 `cache.open` 方法后才可以缓存文件
    caches.open(currentCacheName).then(function(cache) {
    // arrayOfFilesToCache 为存放缓存文件的数组
      return cache.addAll(arrayOfFilesToCache);
    })
  );
});

event.waitUntil() 方法接收三个 promise 对象, 假若那么些 promise 对象 rejectedservice Worker 安装战败,状态更动为 Redundant。关于 cache 相关表达看下文。

步骤2:在cli配置中启用service worker:

要开启Angular service worker,cli必得在编译时生成Angular service worker的布置。要在旧项目中通知cli去做这一步,必需把.angular-cli.json文件里的 serviceWorker的值改成true

ng set apps.0.serviceWorker=true

Service Worker的设置步骤

在页面上成功登记手续之后,让大家把注意力转到service worker的脚本里来,在那当中,大家要形成它的设置步骤。

在最基本的例证中,你必要为install事件定义八个callback,并决定怎么样文件你想要缓存。

JavaScript

// The files we want to cache var urlsToCache = [ '/', '/styles/main.css', '/script/main.js' ]; // Set the callback for the install step self.addEventListener('install', function(event) { // Perform install steps });

1
2
3
4
5
6
7
8
9
10
11
// The files we want to cache
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];
 
// Set the callback for the install step
self.addEventListener('install', function(event) {
    // Perform install steps
});

在大家的install callback中,大家需求进行以下步骤:

  1. 拉开三个缓存
  2. 缓存我们的公文
  3. 决定是或不是享有的财富是不是要被缓存

JavaScript

var CACHE_NAME = 'my-site-cache-v1'; var urlsToCache = [ '/', '/styles/main.css', '/script/main.js' ]; self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];
 
self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

上边的代码中,大家透过caches.open打开大家指定的cache文件名,然后大家调用cache.addAll并传播我们的文件数组。那是经过种类promise(caches.open 和 cache.addAll)完结的。event.waitUntil得到贰个promise并利用它来获取安装耗费的时辰以及是还是不是安装成功。

假如全体的文本都被缓存成功了,那么service worker就安装成功了。假如其它三个文书下载战败,那么安装步骤就能够退步。那个主意允许你依据于您自个儿内定的装有能源,但是那象征你必要十二分谨小慎微地操纵哪些文件供给在安装步骤中被缓存。钦赐了太多的文书的话,就可以扩展设置退步率。

上边只是二个不难的例子,你能够在install事件中推行别的操作照旧以至忽视install事件。

Installed / Waiting

设置到位待正在周转的 service Worker 交接的情事。
Service Worker registration 对象, 大家得以拿走那么些情景

/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {  
    if (registration.waiting) {
        // Service Worker is Waiting
    }
})

那是二个晋升客户更新的好时机,恐怕能够静默更新。

手续3:导入和注册service worker:

src/app/app.module.ts中:

import  {  [ServiceWorkerModule](https://angular.io/api/service-worker/ServiceWorkerModule)  }  from  '@angular/service-worker';  
import  { environment }  from  '../environments/environment';

@NgModule({ 
declarations:  [  AppComponent  ], 
imports:  [  
   BrowserModule,  
   ServiceWorkerModule.register('/ngsw-worker.js',  {enabled: environment.production})  
   ], 
   providers:  [ ],
   bootstrap:  [AppComponent]
 })  
export  class  AppModule  {  }

ngsw-worker.js文件是cli编写翻译生成的service worker脚本,最后能在dist/里找到。

什么缓存和重回Request

您曾经安装了service worker,你今后能够回去您缓存的供给了。

当service worker棉被服装置成功还要客商浏览了另一个页面或然刷新了现阶段的页面,service worker将开头抽出到fetch事件。下边是叁个例子:

JavaScript

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } return fetch(event.request); } ) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
 
        return fetch(event.request);
      }
    )
  );
});

上边的代码里大家定义了fetch事件,在event.respondWith里,大家传入了三个由caches.match发生的promise.caches.match 查找request中被service worker缓存命中的response。

若是大家有三个命中的response,大家回到被缓存的值,不然我们重返三个实时从互连网央求fetch的结果。那是贰个特别轻松的例证,使用全部在install步骤下被缓存的能源。

只要大家想要增量地缓存新的伸手,大家得以由此拍卖fetch央浼的response何况增加它们到缓存中来兑现,譬喻:

JavaScript

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } // IMPORTANT: Clone the request. A request is a stream and // can only be consumed once. Since we are consuming this // once by cache and once by the browser for fetch, we need // to clone the response var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
 
        // IMPORTANT: Clone the request. A request is a stream and
        // can only be consumed once. Since we are consuming this
        // once by cache and once by the browser for fetch, we need
        // to clone the response
        var fetchRequest = event.request.clone();
 
        return fetch(fetchRequest).then(
          function(response) {
            // Check if we received a valid response
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }
 
            // IMPORTANT: Clone the response. A response is a stream
            // and because we want the browser to consume the response
            // as well as the cache consuming the response, we need
            // to clone it so we have 2 stream.
            var responseToCache = response.clone();
 
            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });
 
            return response;
          }
        );
      })
    );
});

代码里大家所做思想政治工作包含:

  1. 丰硕一个callback到fetch恳求的 .then 方法中
  2. 要是大家收获了贰个response,我们开展如下的反省:
    1. 保证response是一蹴而就的
    2. 检查response的事态是或不是是200
    3. 保证response的门类是basic,那象征乞求小编是同源的,非同源(即跨域)的呼吁也无法被缓存。
  3. 如果大家经过了检查,clone本条央求。这么做的开始和结果是只要response是叁个Stream,那么它的body只可以被读取一遍,所以大家得将它克隆出来,一份发给浏览器,一份发给缓存。

Activating

  • 当页面没有正在周转的 service Worker时;
  • service Worker本子中调用了 self.skipWaiting 方法;
  • 客商切换页面使原有的 service Worker 释放;
  • 一定失效已过,释放由此原有的 service Worker 被释放

则状态成为 activating,触发 service workeractive 事件。

/* In sw.js */
self.addEventListener('activate', function(event) {  
  event.waitUntil(
    // Get all the cache names
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        // Get all the items that are stored under a different cache name than the current one
        cacheNames.filter(function(cacheName) {
          return cacheName != currentCacheName;
        }).map(function(cacheName) {
          // Delete the items
          return caches.delete(cacheName);
        })
      ); // end Promise.all()
    }) // end caches.keys()
  ); // end event.waitUntil()
});

install 事件中的 event.waitUntil 方法。当所选拔的 promisereject 那么 serviceWorker 进入 Redundant状态。

手续4: 新建配置文件, ngsw-config.json

angular cli需求名字为ngsw-config.json的service worker配置文件。那文件定义了哪些去缓存文件与数码能源。

你可以行使cli发生的通用配置版本

要么,将以下内容保存为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/**"
      ]
    }
  }]
}

怎么立异五个Service Worker

你的service worker总有亟待创新的那一天。当那一天来到的时候,你供给依据如下步骤来更新:

  1. 革新您的service worker的JavaScript文件
    1. 当顾客浏览你的网址,浏览器尝试在后台下载service worker的台本文件。只要服务器上的文本和本三步跳件有一个字节不一致,它们就被判断为索要更新。
  2. 立异后的service worker将初阶运作,install event被再一次触发。
  3. 在那些日子节点上,当前页不纯熟效的如故是老版本的service worker,新的servicer worker将步向”waiting”状态。
  4. 此时此刻页面被关门之后,老的service worker进度被杀死,新的servicer worker正式生效。
  5. 设若新的service worker生效,它的activate事件被触发。

代码更新后,平时必要在activate的callback中推行三个管制cache的操作。因为你会须求排除掉之前旧的数目。大家在activate实际不是install的时候实行这几个操作是因为假若我们在install的时候马上实施它,那么还是在运维的旧版本的多少就坏了。

在此以前咱们只行使了四个缓存,叫做my-site-cache-v1,其实我们也可以使用多个缓存的,例如一个给页面使用,一个给blog的内容提交使用。这意味着,在install步骤里,我们可以创建两个缓存,pages-cache-v1和blog-posts-cache-v1,在activite步骤里,我们可以删除旧的my-site-cache-v1。

上边包车型大巴代码能够循环全数的缓存,删除掉全部不在白名单中的缓存。

JavaScript

self.addEventListener('activate', function(event) { var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
self.addEventListener('activate', function(event) {
 
  var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1'];
 
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Actived

activting成功后,这时 service Worker 接管了上上下下页面状态成为 acticed
本条地方大家可以阻挡央求和新闻。

/* In sw.js */

self.addEventListener('fetch', function(event) {  
  // Do stuff with fetch events
});

self.addEventListener('message', function(event) {  
  // Do stuff with postMessages received from document
});

步骤 5: 编写翻译项目

ng build --prod

爆发的门类便是启用了Angular service worker了.

拍卖边界和填坑

这一节内容比较新,有无数待定细节。希望这一节非常的慢就无需讲了(因为规范会管理这一个主题素材——译者注),可是今后,这么些剧情依旧应该被提一下。

Redundant

service Workerinstall active进度中处错误可能,被新的 service Worker 替换状态会产生 Redundant

假使是后一种情状,则该 worker 照旧调整这些页面。

值得注意的是一度 installservice worker 页面关闭后再打开不会触发 install 事件,可是会重复登记。更加多参谋作品 商量 Service Worker 「生命周期」

Service worker 的显得表明

此模块通过三个演示来显示表明service worker

假诺设置退步了,未有很名贵的点子获得通报

倘使贰个worker被登记了,然则尚未出现在chrome://inspect/#service-workers或chrome://serviceworker-internals,那么很可能因为异常而安装失败了,或者是产生了一个被拒绝的的promise给event.waitUtil。

要化解那类难题,首先到 chrome://serviceworker-internals检查。打开开发者工具窗口准备调试,然后在你的install event代码中添加debugger;语句。这样,通过断点调试你更容易找到问题。

呼吁处理

处于 actived 阶段的 service Worker 能够阻止页面发出的 fetch,也能够产生fetch央求,能够将诉求和响应缓存在 cache里,也足以将 responsecache 中取出。

运用http-server创设服务器

因为ng serve 不会运维service worker,你必须利用另二个http服务器去地方测验你的品类。你能够利用别的的HTTP服务器。上面例子是应用http-server,能够透过npm安装。为了削减争执的大概性,就要多个专项使用的端口测量试验。
要使用http-server敞开服务,要运动到打包文件的文本夹内然后运转web服务:

cd dist
http-server -p 8080

fetch()这几天仅帮助Service Workers

fetch马上协理在页面上采用了,不过如今的Chrome落成,它还只支持service worker。cache API也快要在页面上被支持,但是近日截止,cache也还只可以在service worker中用。

缓存使用政策

据此得以依赖使用的现象,使用缓存的 response 给到页面收缩乞求及时响应,亦恐怕将需要重返的结果更新到缓存,在应用离线时回来给页面。那正是以下的有余国策。

  1. 网络优先: 从互连网获取, 战败或许逾期再品尝从缓存读取
  2. 缓存优先: 从缓存获取, 缓存插叙不到再品尝从互连网抓取,在上文中的代码块就是该种战术的落到实处。
  3. 最快: 同不时间询问缓存和互联网, 再次来到最早获得的
  4. 只限网络: 仅从网络得到
  5. 只限缓存: 仅从缓存获取

首先加载

劳务运维中,你能够在浏览器访谈http://localhost:8080/。你的利用应该是例行运作。

提示:当测量检验Angular service workers,最佳是在浏览器中动用无痕或私有窗口,那能确定保证service worker不会从先前的留下的缓存中读取数据,变成意外的气象。

fetch()的暗中认可参数

当你采纳fetch,缺省级地区级,央浼不会带上cookies等凭证,要想带上的话,供给:

JavaScript

fetch(url, { credentials: 'include' })

1
2
3
fetch(url, {
  credentials: 'include'
})

这么设计是有理由的,它比XH科雷傲的在同源下暗许发送凭据,但跨域时放任凭据的准绳要来得好。fetch的表现更像别的的COEvoqueS央浼,举例<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。

示例

fetch 基于stream 的 ,因此 response & request 一旦被开销则无从恢复生机,所以那边在缓存的时候须要采取 clone 方法在耗费前复制一份。

self.addEventListener('fetch', function(event) {
// 只对 get 类型的请求进行拦截处理
  if (event.request.method !== 'GET') {
    console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
    return;
  }
  event.respondWith(
  // 缓存中匹配请求
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;
        }

        // 因为 event.request 流已经在 caches.match 中使用过一次,
        // 那么该流是不能再次使用的。我们只能得到它的副本,拿去使用。
        var fetchRequest = event.request.clone();

        // fetch 的通过信方式,得到 Request 对象,然后发送请求
        return fetch(fetchRequest).then(
          function(response) {
            // 检查是否成功
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            // 如果成功,该 response 一是要拿给浏览器渲染,而是要进行缓存。
            // 不过需要记住,由于 caches.put 使用的是文件的响应流,一旦使用,
            // 那么返回的 response 就无法访问造成失败,所以,这里需要复制一份。
            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
    );
});

模仿互连网难点

要效仿网络难点,可禁绝行使的网络连接。在Chrome内:

  1. Select Tools > Developer Tools (开拓人士工具).
  2. 进入Network分页.
  3. 勾选the Offline 项.

图片 3

Now the app has no access to network interaction.
今天应用无法访谈网络了。

对此那么些并未有利用Angular service worker的利用,刷新页面会展现 "There is no Internet connection"的页面。

增加了Angular service worker的行使不均等。刷新后,页面平常呈现。
举例你查看Network 分页的消息,你就能够验证service worker是在劳作。

图片 4

Non-COLacrosseS默许不辅助

暗许景况下,从第三方ULANDL跨域得到叁个能源将会失败,除非对方协理了CO凯雷德S。你能够拉长三个non-CO瑞虎S选项到Request去防止退步。代价是那样做会再次来到二个“不透明”的response,意味着你不可能搜查捕获那一个央求毕竟是大功告成了也许败北了。

JavaScript

cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) { return new Request(urlToPrefetch, { mode: 'no-cors' }); })).then(function() { console.log('All resources have been fetched and cached.'); });

1
2
3
4
5
cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
  return new Request(urlToPrefetch, { mode: 'no-cors' });
})).then(function() {
  console.log('All resources have been fetched and cached.');
});

极品实施

什么样被缓存

会意识全部用来渲染app的公文都被缓存了。给cli使用的通用ngsw-config.json正是概念了缓存那几个特定的财富:

  • index.html.
  • favicon.ico.
  • 编写翻译的公文 (JS and CSS bundles).
  • assets文件夹里的有着文件.

fetch()不遵从30x重定向标准

噩运,重定向在fetch()中不会被触发,那是日前版本的bug;

Register 时机

service Worker 将激化对 CPU 时间和内部存储器的争用,进而影响浏览器渲染以及网页的并行。Chrome 团队的开辟者 杰夫 Posnick 推行声明在展现动画时期注册 service Worker 会导致低级移动设备出现卡顿,因而在这种情景下延后注册或等更加好的顾客体验。

//Bad
window.addEventListener('DOMContentLoaded', function() {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {

    }).catch(function(err) {

    }); 
  });


// Good
if ('serviceWorker' in navigator) {
// 判断浏览器支持情况
  window.addEventListener('load', function() {
  // 页面所有资源加载完成后注册
    navigator.serviceWorker.register('/service-worker.js');
  });
}

然而当你利用 clients.claim()service Worker 调整全数

修改你的使用

近期你早就看见service worker怎么着缓存你的选用,下一步是知道更新怎么着职业。

  1. 如果您在三个无痕窗口中测量检验,展开另二个分页。那会使事态和缓存不会再测量试验中冲消。
  2. 闭馆应用的分页,但不是浏览器。这也会关闭了开荒者工具。
  3. 关闭http-server的服务。
  4. 下一步,修改应用,查看service worker安装更新。
  5. 打开src/app/app.component.html并编辑
  6. 修改文件 Welcome to {{title}}! 为 Bienvenue à {{title}}!.
  7. 双重编写翻译并运行服务
ng build --prod
cd dist
http-server -p 8080

拍卖响应式图片

img的srcset属性可能<picture>标签会根据情况从浏览器或者网络上选择最合适尺寸的图片。

在service worker中,你想要在install步骤缓存一个图纸,你有以下二种采取:

  1. 设置具备的<picture>元素或者将被请求的srcset属性。
  2. 设置单一的low-res版本图片
  3. 设置单一的high-res版本图片

比较好的方案是2或3,因为假诺把装有的图样都给下载下来存着有一点浪费内存。

借让你将low-res版本在install的时候缓存了,然后在页面加载的时候你想要尝试从网络上下载high-res的版本,然则假使high-res版本下载战败以来,就照样用low-res版本。这些主见很好也值得去做,然则有贰个主题素材:

万一大家有上边三种图片:

Screen Density Width Height
1x 400 400
2x 800 800

HTML代码如下:

JavaScript

<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x" />

1
<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x" />

倘使大家在贰个2x的体现方式下,浏览器会下载image-2x.png,假如我们离线,你能够读取从前缓存并赶回image-src.png替代,若是此前它曾经被缓存过。尽管如此,由于现行反革命的情势是2x,浏览器会把400X400的图形展现成200X200,要制止这几个标题就要在图纸的体制上安装宽高。

JavaScript

<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x" style="width:400px; height: 400px;" />

1
2
<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x"
style="width:400px; height: 400px;" />

图片 5

<picture>标签情况更复杂一些,难度取决于你是如何创建和使用的,但是可以通过与srcset类似的思路去解决。

install 事件中静态财富缓存

service Workerinstall 事件中缓存文件进程中,当个中二个文件加载退步,则 install 失败。因而能够对要缓存的文书举办独家,一定要加载的,和允许加载退步的,对于同意加载战败的公文。

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('mygame-core-v1').then(function(cache) {
    // 不稳定文件或大文件加载
      cache.addAll(
        //...
      );
      // 稳定文件或小文件加载
      return cache.addAll(
        // core assets & levels 1-10
      );
    })
  );
});

在浏览器中立异您的利用

当今侦察浏览器和service worker是如何管理更新了的运用

  1. 在长期以来浏览器再一次打开http://localhost:8080 。产生什么?

    图片 6

哪里出错了?实际是没有的。Angular service
worker就在执行它的工作,展示它已安装的应用的版本。尽管有一个可用的更新。为了提高速度,service
worker会在完成展示已缓存的应用后才去检查更新。

若是你查看http-server的日记,你就足以观望service worker央浼/ngsw.json。那是service worker在检查更新。

  1. 刷新页面.

图片 7

service worker在后台装置了更新的app版本,后一次页面加载或重加载时,service worker就展示最新的版本。

改变URL Hash的Bug

在M40版本中设有一个bug,它会让页面在退换hash的时候造成service worker甘休职业。

您能够在这里找到越来越多相关的音信: 

拍卖伏乞中离线景况

service Worker 发送伏乞时,捕获十分,并重临页面四个 response 公告页面或然离线。

function unableToResolve () {
  /* 
    当代码执行到这里,说明请求无论是从缓存还是走网络,都无法得到答复,这个时机,我们可以返回一个相对友好的页面,告诉用户,你可能离线了。
  */
  console.log('WORKER: fetch request failed in both cache and network.');
  return new Response('<h1>Service Unavailable</h1>', {
    status: 503,
    statusText: 'Service Unavailable',
    headers: new Headers({
      'Content-Type': 'text/html'
    })
  });
}
fetch(event.request).then(fetchedFromNetwork, unableToResolve).catch(unableToResolve);

更加多的有关 Angular service workers

您或者对以下感兴趣

  • 与service workers的交互.

你们的夸赞是本身的极度引力

更加多内容

此间有一点相关的文书档案可以参照:

引进按钮机制

按钮是在饿了么实施经验里建议降级方案,通过向后端央求叁个是还是不是降级的接口,如若降级则撤消掉已经注册的service Worker。这里要注意不要缓存那么些开关央求。为了便利难点排查,能够安装三个debug 方式(在 url 增多有个别字符)。

获得扶持

假如您遇上麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于我们及时跟进和不择手腕支持你消除难题。

赞 2 收藏 评论

图片 8

荒谬监察和控制

self.addEventListener('error', event => {
  // 上报错误信息
  // 常用的属性:
  // event.message
  // event.filename
  // event.lineno
  // event.colno
  // event.error.stack
})
// 捕获 promise 错误
self.addEventListener('unhandledrejection', event => {
  // 上报错误信息
  // 常用的属性:
  // event.reason
})

那多个事件都只好在 worker 线程的 initial 生命周期里登记。(不然会退步,调整台可看出警告)

Google 开辟工具助力 service worker 开拓

Google 提供了 sw-toolboxsw-precache 三个工具方便快速生成 service-worker.js 文件:

  • sw-precache用于转移页面所需静态能源列表,目前有 webpack 插件 sw-precache-webpack-plugin 能够相称
  • sw-toolbox 提供了动态缓存使用的通用计策, 那一个动态的财富不合适用 sw-precache 预先缓存。同一时间它提供了一套类似 Express.js 路由的语法, 用于编写计策。它还提供了 LRU 替换攻略与 TTL 失效机制,能够确定保障大家的选取不会超越浏览器的缓存分配的定额。

更多[参照小说]([PWA 入门: 精晓和开创 Service Worker 脚本])

注意事项

  • 作用域:出于安全原因, Service Worker 脚本的功效范围无法超过脚本文件所在的门路。举个例子地址是 "/sw-test/sw.js" 的剧本只可以调节 "/sw-test/" 下的页面。
  • 本地开采条件得以选拔 http 合同, 上线必得选用https 协议。
  • Service Worker 中的 Javascript 代码必需是非阻塞的,所以你不应当在 Service Worker 代码中是用 localStorage 以及 XMLHttpRequest
  • 在页面关闭后,浏览器能够一而再保持service worker运转,也能够关闭service worker,这有赖于与浏览器本人的作为,所以并非在 serviceWorker.js 中定义全局变量,假如想要保存一些长久化的信息,你能够在service worker里使用IndexedDB API。

参考

MDN
Service Worker lifecycle
service worker note
update service worker
chrom service worker sample
PWA 入门: 了解和创办 Service Worker 脚本
PWA 在饿了么的试行经验

本文由澳门太阳娱乐集团官网发布于网页制作,转载请注明出处:[翻译]入门angular的 Service Workers

上一篇:第一篇:基本选择 下一篇:没有了
猜你喜欢
热门排行
精彩图文