澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:worker完毕加速,入门教程

2019-05-17 作者:澳门新萄京赌场网址   |   浏览(182)

Service Worker初体验

2016/01/06 · JavaScript · Service Worker

初稿出处: AlloyTeam   

在201四年,W3C发表了service worker的草案,service worker提供了广大新的技艺,使得web app具备与native app同样的离线体验、音讯推送体验。
service worker是一段脚本,与web worker一样,也是在后台运营。作为一个独立的线程,运维景况与日常脚本差异,所以不能够直接参加web交互行为。native app能够产生离线使用、音讯推送、后台自动更新,service worker的出现是多亏为了使得web app也得以具备类似的本事。

 

service worker可以:

  1. 后台音讯传递
  2. 网络代理,转发呼吁,伪造响应
  3. 离线缓存
  4. 音信推送
  5.  … …

本文以能源缓存为例,说澳优(Ausnutria Hyproca)下service worker是如何专门的学问的。

连不上网?英帝国卫报的秉性离线页面是如此做的

2015/11/20 · HTML5 · Service Worker, 离线页面

本文由 伯乐在线 - Erucy 翻译,weavewillg 校稿。未经许可,禁止转发!
英文出处:Oliver Ash。招待参加翻译组。

大家是怎样利用 service worker 来为 theguardian.com 创设贰个自定义的离线页面。

澳门新萄京官方网站 1

theguardian.com 的离线页面。插图:奥利弗 Ash

你正在朝着集团途中的大巴里,在二弟大上张开了 Guardian 应用。地铁被隧道包围着,可是那一个应用能够健康运营,尽管未有互联网连接,你也能赢得完整的职能,除了出示的原委大概有点旧。倘若你品尝在网址上也那样干,可惜它完全没办法加载:

澳门新萄京官方网站 2

安卓版 Chrome 的离线页面

Chrome 中的这么些彩蛋,很多少人都不明了》

Chrome 在离线页面上有个藏匿的八日游(桌面版上按空格键,手提式有线话机版上点击那只恐龙),那有一点能缓慢化解一点您的烦心。可是大家能够做得更加好。

Service workers 允许网址小编拦截自身站点的享有互连网请求,这也就表示我们得以提供完善的离线体验,就像是原生应用同样。在 Guardian 网址,大家近些日子上线了贰个自定义的离线体验效果。当用户离线的时候,他们会看到三个分包 Guardian 标记的页面,下面带有1个简约的离线提示,还有多个填字游戏,他们能够在等候互连网连接的时候玩玩那几个找点乐子。那篇博客解释了我们是什么样营造它的,可是在上马从前,你能够先自个儿探寻看。

Service Worker入门

2015/03/26 · JavaScript · Service Worker

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

  • 十年踪迹]()   

原生App具备Web应用一般所不具备的富离线体验,定期的沉默更新,音信文告推送等功效。而新的Serviceworkers标准让在Web App上全部这一个职能成为大概。

渐进式Web应用(PWA)入门教程(下)

2018/05/25 · 基本功技艺 · PWA

初稿出处: Craig Buckler   译文出处:山葫芦城控件   

上篇小说我们对渐进式Web应用(PWA)做了有个别中央的牵线。

渐进式Web应用(PWA)入门教程(上)

在那1节中,我们将介绍PWA的规律是怎么样,它是如何初叶专门的职业的。

使用Service worker达成加速/离线访问静态blog网址

2017/02/19 · JavaScript · Service Worker

原版的书文出处: Yang Bo   

前几日相当流行基于Github page和markdown的静态blog,极度适合本事的研商和习于旧贯,针对区别的语言都有一对完好无损的静态blog系统出现,如Jekyll/Ruby,Pelican/Python,Hexo/NodeJs,由于静态内容的特征极其适合做缓存来加速页面包车型大巴访问,就选拔Service worker来达成加速,结果是除了PageSpeed,CDN这几个附近的服务器和互联网加速之外,通过客户端完结了越来越好的拜会体验。

生命周期

先来看一下一个service worker的运转周期

澳门新萄京官方网站 3
上海体育场所是service worker生命周期,出处

图中能够看出,1个service worker要经历以下进度:

  1.  安装

二.  激活,激活成功之后,展开chrome://inspect/#service-workers能够查看到近来运转的service worker

澳门新萄京官方网站 4

  1. 监听fetch和message事件,上边三种事件会议及展览开简要描述

  2. 销毁,是不是销毁由浏览器决定,借使二个service worker短时间不选择还是机器内部存款和储蓄器有数,则只怕会销毁这些worker

试试看

你须求一个协理 Service Worker 和 fetch API 的浏览器。停止到本文编写时只有Chrome(手提式有线话机版和桌面版)同时辅助那二种 API(译者注:Opera 近日也匡助那多头),然则 Firefox 异常快将要协理了(在天天更新的版本中已经帮忙了),除去 Safari 之外的具有浏览器也都在尝试。其它,service worker 只好登记在应用了 HTTPS 的网址上,theguardian.com 已经初步慢慢搬迁到 HTTPS,所以大家只可以在网址的 HTTPS 部分提供离线体验。就当下以来,大家选拔了 开采者博客 作为大家用来测试的地点。所以只要您是在大家网址的 开辟者博客 部分阅读那篇文章的话,很幸运。

当你选拔支持的浏览器访问大家的 开采者博客 中的页面包车型大巴时候,1切就企图妥帖了。断开你的互连网连接,然后刷新一下页面。假设您自个儿没条件尝试的话,能够看一下这段 示范录制(译者注:需梯子)。

Service Worker 是什么?

贰个 service worker 是1段运营在浏览器后台进程里的脚本,它独自于方今页面,提供了这一个无需与web页面交互的功用在网页背后悄悄试行的工夫。在明天,基于它能够兑现音信推送,静默更新以及地理围栏等服务,然则近期它首先要有所的功力是挡住和管理互连网请求,包涵可编制程序的响应缓存管理。

缘何说那几个API是多少个要命棒的API呢?因为它使得开垦者能够支撑非常好的离线体验,它赋予开拓者完全调节离线数据的技巧。

在service worker建议在此以前,此外1个提供开垦者离线体验的API叫做App Cache。可是App Cache有个别局限性,举例它能够很轻便地化解单页应用的难点,可是在多页应用上会很辛苦,而Serviceworkers的出现正是为了化解App Cache的痛点。

上面详细说一下service worker有哪些需求小心的地点:

  • 它是JavaScript Worker,所以它无法一贯操作DOM。但是service worker能够经过postMessage与页面之间通讯,把音讯文告给页面,即使供给的话,让页面自个儿去操作DOM。
  • Serviceworker是2个可编程的互连网代理,允许开垦者调整页面上管理的网络请求。
  • 在不被利用的时候,它会友善终止,而当它再也被用到的时候,会被再一次激活,所以您不可能依附于service worker的onfecth和onmessage的管理函数中的全局状态。假诺您想要保存一些长久化的消息,你能够在service worker里使用IndexedDB API。
  • Serviceworker大批量使用promise,所以壹旦你不打听怎样是promise,那您须求先读书这篇文章。

第一步:使用HTTPS

渐进式Web应用程序必要运用HTTPS连接。纵然选拔HTTPS会令你服务器的成本变多,但使用HTTPS可以让您的网址变得更安全,HTTPS网址在谷歌(Google)上的排名也会更靠前。

是因为Chrome浏览器会暗许将localhost以及1贰七.x.x.x地点视为测试地点,所以在本示例中你并不须要开启HTTPS。其它,出于调节和测试目标,您能够在运营Chrome浏览器的时候使用以下参数来关闭其对网址HTTPS的自小编谈论:

  • –user-data-dir
  • –unsafety-treat-insecure-origin-as-secure

加紧/离线访问只需三步

  • 首页增多注册代码

JavaScript

<script> if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js'); } </script>

1
2
3
4
5
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
</script>
  • 复制代码

将保存到你的网站根目录下

  • 修改不缓存域名列表及离线状态页面

在你的sw.js中修改

JavaScript

const ignoreFetch = [ /https?://cdn.bootcss.com//, /https?://static.duoshuo.com//, /https?://www.google-analytics.com//, /https?://dn-lbstatics.qbox.me//, ];

1
2
3
4
5
6
const ignoreFetch = [
  /https?://cdn.bootcss.com//,
  /https?://static.duoshuo.com//,
  /https?://www.google-analytics.com//,
  /https?://dn-lbstatics.qbox.me//,
];

打开Chrome Dev Tools->Source,看看自个儿的blog都引用了什么第二方能源,每个加到忽略列表里。

澳门新萄京官方网站 5

在根目录下增加offline.html,在并未有网络且缓存中也从没时采取,效果如下:

澳门新萄京官方网站 6

在根目录下加多offline.svg,在无网络时图片能源请求重返该公文。

fetch事件

在页面发起http请求时,service worker能够透过fetch事件拦截请求,并且付诸本人的响应。
w三c提供了三个新的fetch api,用于代替XMLHttpRequest,与XMLHttpRequest最大差异有两点:

一. fetch()方法重临的是Promise对象,通过then方法开展连接调用,收缩嵌套。ES陆的Promise在成为标准之后,会愈发方便开拓职员。

二. 提供了Request、Response对象,借使做过后端开荒,对Request、Response应该相比熟识。前端要发起呼吁能够透过url发起,也足以选取Request对象发起,而且Request可以复用。不过Response用在何地吗?在service worker出现以前,前端确实不会融洽给本人发信息,可是有了service worker,就能够在拦截请求之后听大人讲需求发回本人的响应,对页面来讲,那个平凡的伏乞结果并从未分别,那是Response的壹处选取。

上面是在中,小编利用fetch api通过fliker的公开api获取图片的例子,注释中详尽表明了每一步的成效:

JavaScript

/* 由于是get请求,直接把参数作为query string传递了 */ var URL = ''; function fetchDemo() { // fetch(url, option)扶助五个参数,option中能够安装header、body、method新闻fetch(UPAJEROL).then(function(response) { // 通过promise 对象获得相应内容,并且将响应内容根据json格式转成对象,json()方法调用之后回到的照旧是promise对象 // 也能够把内容转化成arraybuffer、blob对象 return response.json(); }).then(function(json) { // 渲染页面 insertPhotos(json); }); } fetch德姆o();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 由于是get请求,直接把参数作为query string传递了 */
var URL = 'https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=your_api_key&format=json&nojsoncallback=1&tags=penguins';
 
function fetchDemo() {
  // fetch(url, option)支持两个参数,option中可以设置header、body、method信息
  fetch(URL).then(function(response) {
    // 通过promise 对象获得相应内容,并且将响应内容按照json格式转成对象,json()方法调用之后返回的依然是promise对象
    // 也可以把内容转化成arraybuffer、blob对象
    return response.json();
  }).then(function(json) {
    // 渲染页面
    insertPhotos(json);
  });
}
 
fetchDemo();

fetch api与XMLHttpRequest比较,尤其简洁,并且提供的法力更完美,能源获得方式比ajax更优雅。包容性方面:chrome 42初叶接济,对于旧浏览器,能够经过合法维护的polyfill辅助。

行事规律

因而1段轻易的 JavaScript,大家能够提示浏览器在用户访问页面的时候立刻登记我们和好的 service worker。近日补助 service worker 的浏览器很少,所感到了幸免不当,我们必要利用个性检查评定。

JavaScript

if (navigator.serviceWorker) { navigator.serviceWorker.register('/service-worker.js'); }

1
2
3
if (navigator.serviceWorker) {
    navigator.serviceWorker.register('/service-worker.js');
}

Service worker 安装事件的一局部,大家得以选用 新的缓存 API 来缓存大家网址中的各类内容,比方 HTML、CSS 和 JavaScript:

JavaScript

var staticCacheName = 'static'; var version = 1; function updateCache() { return caches.open(staticCacheName version) .then(function (cache) { return cache.addAll([ '/offline-page.html', '/assets/css/main.css', '/assets/js/main.js' ]); }); }; self.addEventListener('install', function (event) { event.waitUntil(updateCache()); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var staticCacheName = 'static';
var version = 1;
 
function updateCache() {
    return caches.open(staticCacheName version)
        .then(function (cache) {
            return cache.addAll([
                '/offline-page.html',
                '/assets/css/main.css',
                '/assets/js/main.js'
            ]);
        });
};
 
self.addEventListener('install', function (event) {
    event.waitUntil(updateCache());
});

当安装到位后,service worker 能够监听和调控 fetch 事件,让大家能够完全调控之后网址中爆发的有着互联网请求。

JavaScript

self.addEventListener('fetch', function (event) { event.respondWith(fetch(event.request)); });

1
2
3
self.addEventListener('fetch', function (event) {
    event.respondWith(fetch(event.request));
});

在此地大家有很灵活的上空能够发挥,比方上面这些难点,能够由此代码来生成大家团结的伸手响应:

JavaScript

self.addEventListener('fetch', function (event) { var response = new Response('<h1>Hello, World!</h1>', { headers: { 'Content-Type': 'text/html' } }); event.respondWith(response); });

1
2
3
4
5
self.addEventListener('fetch', function (event) {
    var response = new Response('&lt;h1&gt;Hello, World!&lt;/h1&gt;',
        { headers: { 'Content-Type': 'text/html' } });
    event.respondWith(response);
});

再有那几个,假如在缓存中找到了请求相应的缓存,我们得以平昔从缓存中回到它,若是没找到的话,再通过网络获取响应内容:

JavaScript

self.addEventListener('fetch', function (event) { event.respondWith( caches.match(event.request) .then(function (response) { return response || fetch(event.request); }) ); });

1
2
3
4
5
6
7
8
self.addEventListener('fetch', function (event) {
    event.respondWith(
        caches.match(event.request)
            .then(function (response) {
                return response || fetch(event.request);
            })
    );
});

那便是说大家怎么样使用这么些职能来提供离线体验吧?

第贰,在 service worker 安装进度中,咱们必要把离线页面要求的 HTML 和财富文件通过 service worker 缓存下来。在缓存中,大家加载了自身支付的 填字游戏 的 React应用 页面。之后,大家会阻碍全数访问 theguardian.com 网络请求,包蕴网页、以及页面中的财富文件。处理那个请求的逻辑差不多如下:

  1. 当我们检验到传播请求是指向大家的 HTML 页面时,我们总是会想要提供新型的故事情节,所以大家会尝试把那一个请求通过网络发送给服务器。
    1. 当大家从服务器获得了响应,就足以一贯回到那几个响应。
    2. 固然网络请求抛出了要命(比如因为用户掉线了),大家捕获那些特别,然后接纳缓存的离线 HTML 页面作为响应内容。
  2. 不然,当大家检查测试到请求的不是 HTML 的话,大家会从缓存中追寻响应的乞请内容。
    1. 设若找到了缓存内容,大家得以一贯回到缓存的内容。
    2. 不然,我们会尝试把这一个请求通过网络发送给服务器。

在代码中,大家采用了 新的缓存 API(它是 Service Worker API 的一片段)以及 fetch 效能(用于转移网络请求),如下所示:

JavaScript

var doesRequestAcceptHtml = function (request) { return request.headers.get('Accept') .split(',') .some(function (type) { return type === 'text/html'; }); }; self.addEventListener('fetch', function (event) { var request = event.request; if (doesRequestAcceptHtml(request)) { // HTML pages fallback to offline page event.respondWith( fetch(request) .catch(function () { return caches.match('/offline-page.html'); }) ); } else { // Default fetch behaviour // Cache first for all other requests event.respondWith( caches.match(request) .then(function (response) { return response || fetch(request); }) ); } });

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
var doesRequestAcceptHtml = function (request) {
    return request.headers.get('Accept')
        .split(',')
        .some(function (type) { return type === 'text/html'; });
};
 
self.addEventListener('fetch', function (event) {
    var request = event.request;
    if (doesRequestAcceptHtml(request)) {
        // HTML pages fallback to offline page
        event.respondWith(
            fetch(request)
                .catch(function () {
                    return caches.match('/offline-page.html');
                })
        );
    } else {
        // Default fetch behaviour
        // Cache first for all other requests
        event.respondWith(
            caches.match(request)
                .then(function (response) {
                    return response || fetch(request);
                })
        );
    }
});

就只须要如此多!theguardian.com 上的 装有代码都是在 GitHub 上开源 的,所以您能够去那儿查看大家的 service worker 的一体化版本,可能直接从生育情状上访问 。

咱俩有雄厚的理由为这一个新的浏览器才具欢呼喝彩,因为它能够用来令你的网址像前几天的原生应用同样,拥有完美的离线体验。今后当 theguardian.com 完全迁移到 HTTPS 之后,离线页面包车型客车入眼性会显明扩张,大家得以提供越来越完善的离线体验。设想一下你在上下班路上互联网很差的时候访问 theguardian.com,你会看到特地为你订制的本性化内容,它们是在你后边访问网址时由浏览器缓存下来的。它在设置进程中也不会时有爆发其余困难,你所急需的只是造访那么些网址而已,不像原生应用,还索要用户有1个用到公司的账号技术设置。Serviceworker 同样能够扶助我们提高网站的加载速度,因为网址的框架能够被保证地缓存下来,就如原生应用同样。

比如您对 service worker 很感兴趣,想要驾驭愈来愈多内容的话,开采者 MattGaunt(Chrome的矢忠不贰协助者)写了一篇尤其详实地 介绍 Service Worker的文章。

打赏扶助自个儿翻译更多好小说,多谢!

打赏译者

Service Worker的生命周期

Service worker具备一个通通独立于Web页面包车型客车生命周期。

要让三个service worker在你的网址上生效,你要求先在您的网页中登记它。注册二个service worker之后,浏览器会在后台默默运转二个service worker的安装进程。

在安装进程中,浏览器会加载并缓存一些静态财富。假若具备的文件被缓存成功,service worker就设置成功了。即使有此外文件加载或缓存失利,那么安装进度就能停业,service worker就不可能被激活(也即没能安装成功)。要是爆发如此的难题,别牵挂,它会在后一次再尝试安装。

当安装达成后,service worker的下一步是激活,在这一等第,你还足以荣升3个service worker的版本,具体内容大家会在末端讲到。

在激活之后,service worker将接管全数在和煦管辖域范围内的页面,但是假如三个页面是刚刚注册了service worker,那么它那三回不会被接管,到下三次加载页面包车型客车时候,service worker才会生效。

当service worker接管了页面之后,它也可以有二种意况:要么被截至以节省里部存款和储蓄器,要么会管理fetch和message事件,那四个事件分别发生于二个网络请求出现依然页面上发送了三个信息。

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

澳门新萄京官方网站 7

第3步:成立一个应用程序清单(Manifest)

应用程序清单提供了和脚下渐进式Web应用的相关音信,如:

  • 应用程序名
  • 描述
  • 具有图片(包蕴主荧屏Logo,运维显示器页面和用的图纸或许网页上用的图形)

真相上讲,程序清单是页面上用到的Logo和主旨等能源的元数据。

程序清单是多个放在您使用根目录的JSON文件。该JSON文件重回时必须抬高Content-Type: application/manifest json 或者 Content-Type: application/jsonHTTP头消息。程序清单的文本名不限,在本文的演示代码中为manifest.json

{ "name" : "PWA Website", "short_name" : "PWA", "description" : "An example PWA website", "start_url" : "/", "display" : "standalone", "orientation" : "any", "background_color" : "#ACE", "theme_color" : "#ACE", "icons": [ { "src" : "/images/logo/logo072.png", "sizes" : "72x72", "type" : "image/png" }, { "src" : "/images/logo/logo152.png", "sizes" : "152x152", "type" : "image/png" }, { "src" : "/images/logo/logo192.png", "sizes" : "192x192", "type" : "image/png" }, { "src" : "/images/logo/logo256.png", "sizes" : "256x256", "type" : "image/png" }, { "src" : "/images/logo/logo512.png", "sizes" : "512x512", "type" : "image/png" } ] }

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
{
  "name"              : "PWA Website",
  "short_name"        : "PWA",
  "description"       : "An example PWA website",
  "start_url"         : "/",
  "display"           : "standalone",
  "orientation"       : "any",
  "background_color"  : "#ACE",
  "theme_color"       : "#ACE",
  "icons": [
    {
      "src"           : "/images/logo/logo072.png",
      "sizes"         : "72x72",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo152.png",
      "sizes"         : "152x152",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo192.png",
      "sizes"         : "192x192",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo256.png",
      "sizes"         : "256x256",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo512.png",
      "sizes"         : "512x512",
      "type"          : "image/png"
    }
  ]
}

程序清单文件创建完事后,你必要在各种页面上引用该公文:

<link rel="manifest" href="/manifest.json">

1
<link rel="manifest" href="/manifest.json">

以下属性在程序清单中时时利用,介绍表明如下:

  • name: 用户寓指标施用名称
  • short_name: 应用短名称。当展现采取名称的地点不够时,将使用该名称。
  • description: 应用描述。
  • start_url: 采纳初阶路线,相对路线,暗中同意为/。
  • scope: U本田UR-VL范围。比如:若是您将“/app/”设置为USportageL范围时,那些动用就能够直接在那一个目录中。
  • background_澳门新萄京官方网站,color: 迎接页面包车型客车背景颜色和浏览器的背景颜色(可选)
  • theme_color: 动用的主题颜色,一般都会和背景颜色同样。那个装置决定了接纳如何展示。
  • orientation: 优先旋转方向,可选的值有:any, natural, landscape, landscape-primary, landscape-secondary, portrait, portrait-primary, and portrait-secondary
  • display: 展现方式——fullscreen(无Chrome),standalone(和原生应用同样),minimal-ui(最小的一套UI控件集)也许browser(最古老的利用浏览器标签展现)
  • icons: 2个富含全部图片的数组。该数组中种种元素包罗了图片的U汉兰达L,大小和品种。

加快效果

首页加快后,互联网请求从1陆降为①,加载时间从二.2九陆s降为0.65四s,获得了刹那间加载的结果。

澳门新萄京官方网站 8

基于webpagetest

查看测试结果

message事件

页面和serviceWorker之间能够透过posetMessage()方法发送消息,发送的音信能够因此message事件接收到。

这是1个双向的历程,页面可以发新闻给service worker,service worker也得以发送消息给页面,由于那个特点,能够将service worker作为中间纽带,使得贰个域名如故子域名下的七个页面能够自便通讯。

此处是叁个小的页面之间通讯demo

打赏援助笔者翻译越来越多好小说,多谢!

澳门新萄京官方网站 9

1 赞 收藏 评论

在我们初步写码在此之前

从这个品类地址拿到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的,所以它是3个优良的自发实验田。

如若您想要让您的server补助HTTPS,你须求为你的server拿到3个TLS证书。分裂的server安装方法分裂,阅读协助文书档案并通过Mozilla’s SSL config generator询问最棒试行。

其三步:创立二个 Service Worker

Service Worker 是1个可编制程序的服务器代理,它能够阻碍恐怕响应网络请求。瑟维斯 Worker 是身处应用程序根目录的3个个的JavaScript文件。

您需求在页面前碰到应的JavaScript文件中登记该ServiceWorker:

if ('serviceWorker' in navigator) { // register service worker navigator.serviceWorker.register('/service-worker.js'); }

1
2
3
4
if ('serviceWorker' in navigator) {
  // register service worker
  navigator.serviceWorker.register('/service-worker.js');
}

比如您没有必要离线的相干作用,您能够只开创3个 /service-worker.js文本,那样用户就足以平昔设置您的Web应用了!

ServiceWorker那么些定义只怕相比难懂,它实在是五个做事在其余线程中的标准的Worker,它无法访问页面上的DOM成分,没有页面上的API,但是足以阻挡全部页面上的互联网请求,包蕴页面导航,请求能源,Ajax请求。

地点正是选拔全站HTTPS的最主因了。假设你未有在您的网址中接纳HTTPS,八个第一方的剧本就能够从别的的域名注入他自身的ServiceWorker,然后篡改全数的呼吁——那的确是十分危险的。

Service Worker 会响应八个事件:install,activate和fetch。

增长速度/离线原理研究

行使service workder缓存文件

下边介绍一个选用service worker缓存离线文件的事例
未焚徙薪index.js,用于注册service-worker

JavaScript

if (navigator.serviceWorker) { navigator.serviceWorker.register('service-worker.js').then(function(registration) { console.log('service worker 注册成功'); }).catch(function (err) { console.log('servcie worker 注册失败') }); }

1
2
3
4
5
6
7
if (navigator.serviceWorker) {
    navigator.serviceWorker.register('service-worker.js').then(function(registration) {
        console.log('service worker 注册成功');
    }).catch(function (err) {
        console.log('servcie worker 注册失败')
    });
}

在上述代码中,注册了service-worker.js作为当下路径下的service worker。由于service worker的权柄极高,全数的代码都急需是安全可相信的,所以只有https站点才方可采用service worker,当然localhost是三个特例。
登记停止,以往开端写service-worker.js代码。
基于后边的生命周期图,在1个新的service worker被注册之后,首先会触发install事件,在service-workder.js中,能够通过监听install事件实行局地开头化专业,或然什么也不做。
因为大家是要缓存离线文件,所以能够在install事件中初步缓存,可是只是将文件加到caches缓存中,真正想让浏览器接纳缓存文件须要在fetch事件中阻止

JavaScript

var cacheFiles = [ 'about.js', 'blog.js' ]; self.addEventListener('install', function (evt) { evt.waitUntil( caches.open('my-test-cahce-v1').then(function (cache) { return cache.addAll(cacheFiles); }) ); });

1
2
3
4
5
6
7
8
9
10
11
var cacheFiles = [
    'about.js',
    'blog.js'
];
self.addEventListener('install', function (evt) {
    evt.waitUntil(
        caches.open('my-test-cahce-v1').then(function (cache) {
            return cache.addAll(cacheFiles);
        })
    );
});

先是定义了需求缓存的文件数组cacheFile,然后在install事件中,缓存那些文件。
evt是四个Install伊夫nt对象,承继自Extendable伊芙nt,个中的waitUntil()方法接收二个promise对象,直到那个promise对象成功resolve之后,才会持续运营service-worker.js。
caches是二个CacheStorage对象,使用open()方法展开2个缓存,缓存通过名称举办区分。
获得cache实例之后,调用addAll()方法缓存文件。

那般就将文件增多到caches缓存中了,想让浏览器采用缓存,还索要拦截fetch事件

JavaScript

// 缓存图片 self.add伊夫ntListener('fetch', function (evt) { evt.respondWith( caches.match(evt.request).then(function(response) { if (response) { return response; } var request = evt.request.clone(); return fetch(request).then(function (response) { if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) { return response; } var responseClone = response.clone(); caches.open('my-test-cache-v1').then(function (cache) { cache.put(evt.request, responseClone); }); return response; }); }) ) });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 缓存图片
self.addEventListener('fetch', function (evt) {
    evt.respondWith(
        caches.match(evt.request).then(function(response) {
            if (response) {
                return response;
            }
            var request = evt.request.clone();
            return fetch(request).then(function (response) {
                if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) {
                    return response;
                }
                var responseClone = response.clone();
                caches.open('my-test-cache-v1').then(function (cache) {
                    cache.put(evt.request, responseClone);
                });
                return response;
            });
        })
    )
});

通过监听fetch事件,service worker能够回来自身的响应。

率先检缓存中是还是不是曾经缓存了那几个请求,如果有,就径直重回响应,就减弱了一遍网络请求。不然由service workder发起请求,那时的service workder起到了2在那之中等代理的效能。

service worker请求的进程通过fetch api完毕,获得response对象现在实行过滤,查看是还是不是是图片文件,假设不是,就直接再次回到请求,不会缓存。

假定是图表,要先复制一份response,原因是request或许response对象属于stream,只好动用一回,之后一份存入缓存,另壹份发送给页面。
那就是service worker的强劲之处:拦截请求,伪造响应。fetch api在此处也起到了十分的大的功效。

 

service worker的换代异常粗略,只要service-worker.js的公文内容有更新,就能够使用新的剧本。可是有点要留意:旧缓存文件的铲除、新文件的缓存要在activate事件中张开,因为可能旧的页面还在运用以前的缓存文件,清除之后会错过功能。

 

在初次使用service worker的长河中,也遇到了一些主题素材,上面是里面七个

关于作者:Erucy

澳门新萄京官方网站 10

早就的SharePoint喵星技师(这段时间还挂着微软MVP的名头),未来的Azure/.Net/MongoDB/Cordova/前端程序员,有的时候写小说 个人主页 · 笔者的稿子 · 46 ·   

澳门新萄京官方网站 11

使用Service Worker

近些日子大家有了polyfill,并且化解了HTTPS,让我们看看终归怎么用service worker。

Install事件

该事件将要利用设置到位后触发。大家一般在此地运用Cache API缓存一些要求的文本。

首先,我们供给提供如下配置

  1. 缓存名称(CACHE)以及版本(version)。应用能够有八个缓存存款和储蓄,可是在动用时只会选择个中一个缓存存款和储蓄。每当缓存存款和储蓄有转移时,新的版本号将会钦命到缓存存储中。新的缓存存款和储蓄将会作为当前的缓存存款和储蓄,在此以前的缓存存款和储蓄将会被作废。
  2. 二个离线的页面地址(offlineUPAJEROL):当用户访问了事先并未有访问过的地点时,该页面将会呈现。
  3. 2个涵盖了颇具必须文件的数组,包罗保持页面不奇怪职能的CSS和JavaScript。在本示例中,小编还增加了主页和logo。当有例外的U福睿斯L指向同三个财富时,你也能够将这么些U瑞虎L分别写到这些数组中。offlineU大切诺基L将会投入到这一个数组中。
  4. 笔者们也能够将一些非供给的缓存文件(installFilesDesirable)。这么些文件在装置进程司令员会被下载,但如若下载失败,不会触发安装失败。

// 配置文件 const version = '一.0.0', CACHE = version '::PWAsite', offlineUENCOREL = '/offline/', installFilesEssential = [ '/', '/manifest.json', '/css/styles.css', '/js/main.js', '/js/offlinepage.js', '/images/logo/logo152.png' ].concat(offlineURL), installFilesDesirable = [ '/favicon.ico', '/images/logo/logo016.png', '/images/hero/power-pv.jpg', '/images/hero/power-lo.jpg', '/images/hero/power-hi.jpg' ];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 配置文件
const
  version = '1.0.0',
  CACHE = version '::PWAsite',
  offlineURL = '/offline/',
  installFilesEssential = [
    '/',
    '/manifest.json',
    '/css/styles.css',
    '/js/main.js',
    '/js/offlinepage.js',
    '/images/logo/logo152.png'
  ].concat(offlineURL),
  installFilesDesirable = [
    '/favicon.ico',
    '/images/logo/logo016.png',
    '/images/hero/power-pv.jpg',
    '/images/hero/power-lo.jpg',
    '/images/hero/power-hi.jpg'
  ];

installStaticFiles() 方法运用基于Promise的艺术使用Cache API将文件存款和储蓄到缓存中。

// 安装静态财富 function installStaticFiles() { return caches.open(CACHE) .then(cache => { // 缓存可选文件 cache.addAll(installFilesDesirable); // 缓存必须文件 return cache.addAll(installFilesEssential); }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 安装静态资源
function installStaticFiles() {
  return caches.open(CACHE)
    .then(cache => {
      // 缓存可选文件
      cache.addAll(installFilesDesirable);
      // 缓存必须文件
      return cache.addAll(installFilesEssential);
    });
}

最终,我们增加一个install的风云监听器。waitUntil措施保障了service worker不会安装直到其相关的代码被实行。这里它会实行installStaticFiles()方法,然后self.skipWaiting()办法来激活service worker:

// 应用设置 self.add伊夫ntListener('install', event => { console.log('service worker: install'); // 缓存首要文件 event.waitUntil( installStaticFiles() .then(() => self.skipWaiting()) ); });

1
2
3
4
5
6
7
8
9
10
11
12
// 应用安装
self.addEventListener('install', event => {
  console.log('service worker: install');
  // 缓存主要文件
  event.waitUntil(
    installStaticFiles()
    .then(() => self.skipWaiting())
  );
});

什么是 Service worker

澳门新萄京官方网站 12

如上图,Service worker 是一种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当多个页面注册了八个 Service worker,它就足以登记壹多种事件管理器来响应如网络请求和音讯推送这一个事件。Service worker 能够被用来治本缓存,当响应三个互联网请求时能够布署为回到缓存如故从互联网获取。由于Service worker 是依赖事件的,所以它只在管理那么些事件的时候被调入内部存款和储蓄器,不用忧郁常驻内部存款和储蓄器占用财富导致系统变慢。

难点一. 周转时刻

service worker并不是一贯在后台运转的。在页面关闭后,浏览器能够持续维持service worker运维,也足以关闭service worker,那取决于与浏览器自身的一言一动。所以不用定义一些全局变量,比方上面包车型大巴代码(来自):

JavaScript

var hitCounter = 0; this.addEventListener('fetch', function(event) { hitCounter ; event.respondWith( new Response('Hit number ' hitCounter) ); });

1
2
3
4
5
6
7
8
var hitCounter = 0;
 
this.addEventListener('fetch', function(event) {
  hitCounter ;
  event.respondWith(
    new Response('Hit number ' hitCounter)
  );
});

归来的结果也许是从未规律的:1,2,1,2,1,一,二….,原因是hitCounter并不曾一向留存,借使浏览器关闭了它,下一次运维的时候hitCounter就赋值为0了
这么的业务导致调节和测试代码困难,当您更新多个service worker今后,唯有在打开新页面以往才大概接纳新的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是否对你的网站启用了。

澳门新萄京官方网站 13

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

你会意识这么些效果能够很方便地在一个效仿窗口中测试你的service worker,那样你能够关闭和重复展开它,而不会潜移默化到您的新窗口。任何创制在模仿窗口中的注册服务和缓存在窗口被关门时都将消灭。

Activate 事件

其一事件会在service worker被激活时发生。你或者无需以此事件,可是在演示代码中,大家在该事件时有爆发时将老的缓存全体清理掉了:

// clear old caches function clearOldCaches() { return caches.keys() .then(keylist => { return Promise.all( keylist .filter(key => key !== CACHE) .map(key => caches.delete(key)) ); }); } // application activated self.addEventListener('activate', event => { console.log('service worker: activate'); // delete old caches event.waitUntil( clearOldCaches() .then(() => self.clients.claim()) ); });

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
// clear old caches
function clearOldCaches() {
  return caches.keys()
    .then(keylist => {
      return Promise.all(
        keylist
          .filter(key => key !== CACHE)
          .map(key => caches.delete(key))
      );
    });
}
// application activated
self.addEventListener('activate', event => {
  console.log('service worker: activate');
    // delete old caches
  event.waitUntil(
    clearOldCaches()
    .then(() => self.clients.claim())
    );
});

注意self.clients.claim()执行时将会把最近service worker作为被激活的worker。

Fetch 事件 该事件将会在网络初阶请求时发起。该事件管理函数中,大家得以行使respondWith()办法来胁制HTTP的GET请求然后回来:

  1. 从缓存中取到的财富文件
  2. 要是第3步战败,财富文件将会从网络中动用Fetch API来收获(和service worker中的fetch事件毫不相关)。获取到的能源将会投入到缓存中。
  3. 举个例子第3步和第二步均未果,将会从缓存中回到正确的财富文件。

// application fetch network data self.addEventListener('fetch', event => { // abandon non-GET requests if (event.request.method !== 'GET') return; let url = event.request.url; event.respondWith( caches.open(CACHE) .then(cache => { return cache.match(event.request) .then(response => { if (response) { // return cached file console.log('cache fetch: ' url); return response; } // make network request return fetch(event.request) .then(newreq => { console.log('network fetch: ' url); if (newreq.ok) cache.put(event.request, newreq.clone()); return newreq; }) // app is offline .catch(() => offlineAsset(url)); }); }) ); });

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
40
41
// application fetch network data
self.addEventListener('fetch', event => {
  // abandon non-GET requests
  if (event.request.method !== 'GET') return;
  let url = event.request.url;
  event.respondWith(
    caches.open(CACHE)
      .then(cache => {
        return cache.match(event.request)
          .then(response => {
            if (response) {
              // return cached file
              console.log('cache fetch: ' url);
              return response;
            }
            // make network request
            return fetch(event.request)
              .then(newreq => {
                console.log('network fetch: ' url);
                if (newreq.ok) cache.put(event.request, newreq.clone());
                return newreq;
              })
              // app is offline
              .catch(() => offlineAsset(url));
          });
      })
  );
});

offlineAsset(url)格局中采纳了部分helper方法来回到精确的数码:

// 是或不是为图片地址? let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' f); function isImage(url) { return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false); } // return 再次回到离线能源 function offlineAsset(url) { if (isImage(url)) { // 再次来到图片 return new Response( '<svg role="img" viewBox="0 0 400 300" xmlns=" d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>', { headers: { 'Content-Type': 'image/svg xml', 'Cache-Control': 'no-store' }} ); } else { // return page return caches.match(offlineURL); } }

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
// 是否为图片地址?
let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' f);
function isImage(url) {
  
  return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false);
  
}
  
  
// return 返回离线资源
function offlineAsset(url) {
  
  if (isImage(url)) {
  
    // 返回图片
    return new Response(
      '<svg role="img" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title>offline</title><path d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>',
      { headers: {
        'Content-Type': 'image/svg xml',
        'Cache-Control': 'no-store'
      }}
    );
  
  }
  else {
  
    // return page
    return caches.match(offlineURL);
  
  }
  
}

offlineAsset()主意检查请求是还是不是为3个图纸,然后重回3个富含“offline”文字的SVG文件。别的请求将会重回offlineUSportageL 页面。

Chrome开荒者工具中的ServiceWorker部分提供了关于当前页面worker的新闻。在那之中会显得worker中发生的荒唐,仍是可以强制刷新,也得以让浏览器进入离线情势。

Cache Storage 部分例举了当前享有曾经缓存的财富。你能够在缓存须求更新的时候点击refresh开关。

Service worker生命周期

澳门新萄京官方网站 14

Service worker 为网页增添二个像样于APP的生命周期,它只会响应系统事件,固然浏览器关闭时操作系统也能够提醒Service worker,那点卓殊重要,让web app与native app的力量变得就像了。

Service worker在Register时会触发Install事件,在Install时方可用来预先获取和缓存应用所需的能源并安装每一个文件的缓存计谋。

一旦Service worker远在activated状态,就足以完全调整应用的财富,对网络请求进行反省,修改网络请求,从网络上获得并赶回内容或许再次来到由已安装的Service worker预先报告获取并缓存好的能源,以至还足以转换内容并重临给互连网语法。

不无的这一个都用户都是透明的,事实上,一个安顿卓越的Service worker就像是三个智能缓存系统,加强了互联网和缓存成效,选用最优办法来响应互联网请求,让使用尤其稳固的运作,纵然没有互连网也没提到,因为您能够完全调整网络响应。

主题素材二. 权力太大

当service worker监听fetch事件过后,对应的乞请都会通过service worker。通过chrome的network工具,能够见见此类请求会标明:from service worker。借使service worker中出现了难点,会变成全部请求战败,包涵常见的html文件。所以service worker的代码质量、容错性一定要很好技能确认保证web app寻常运转。

 

参照小说:

1. 

2. 

3. 

4. 

5. 

1 赞 3 收藏 评论

澳门新萄京官方网站 15

Service Worker的设置步骤

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

在最基本的例证中,你供给为install事件定义3个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就安装成功了。尽管其余多少个文书下载退步,那么安装步骤就能够失利。那几个方法允许你依靠于您自身钦赐的有着财富,然而那表示你须要极度严俊地垄断哪些文件须求在设置步骤中被缓存。钦点了太多的文件的话,就能扩展设置退步率。

地点只是3个简易的例证,你可以在install事件中实行其它操作依旧以至忽视install事件。

第5步:创造可用的离线页面

离线页面能够是静态的HTML,一般用来提示用户近日恳请的页面近些日子不大概运用。不过,大家能够提供一些方可翻阅的页面链接。

Cache API能够在main.js中使用。不过,该API使用Promise,在不援救Promise的浏览器中会战败,全数的JavaScript试行会就此遭到震慑。为了幸免这种状态,在造访/js/offlinepage.js的时候大家加多了一段代码来检查当前是或不是在离线境遇中:

/js/offlinepage.js 中以版本号为名称保存了不久前的缓存,获取具备UHavalL,删除不是页面的U奥迪Q3L,将那么些UOdysseyL排序然后将有着缓存的U奥德赛L呈以后页面上:

// cache name const CACHE = '::PWAsite', offlineURL = '/offline/', list = document.getElementById('cachedpagelist'); // fetch all caches window.caches.keys() .then(cacheList => { // find caches by and order by most recent cacheList = cacheList .filter(cName => cName.includes(CACHE)) .sort((a, b) => a - b); // open first cache caches.open(cacheList[0]) .then(cache => { // fetch cached pages cache.keys() .then(reqList => { let frag = document.createDocumentFragment(); reqList .map(req => req.url) .filter(req => (req.endsWith('/') || req.endsWith('.html')) && !req.endsWith(offlineURL)) .sort() .forEach(req => { let li = document.createElement('li'), a = li.appendChild(document.createElement('a')); a.setAttribute('href', req); a.textContent = a.pathname; frag.appendChild(li); }); if (list) list.appendChild(frag); }); }) });

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
40
41
42
43
44
45
// cache name
const
  CACHE = '::PWAsite',
  offlineURL = '/offline/',
  list = document.getElementById('cachedpagelist');
// fetch all caches
window.caches.keys()
  .then(cacheList => {
    // find caches by and order by most recent
    cacheList = cacheList
      .filter(cName => cName.includes(CACHE))
      .sort((a, b) => a - b);
    // open first cache
    caches.open(cacheList[0])
      .then(cache => {
        // fetch cached pages
        cache.keys()
          .then(reqList => {
            let frag = document.createDocumentFragment();
            reqList
              .map(req => req.url)
              .filter(req => (req.endsWith('/') || req.endsWith('.html')) && !req.endsWith(offlineURL))
              .sort()
              .forEach(req => {
                let
                  li = document.createElement('li'),
                  a = li.appendChild(document.createElement('a'));
                  a.setAttribute('href', req);
                  a.textContent = a.pathname;
                  frag.appendChild(li);
              });
            if (list) list.appendChild(frag);
          });
      })
  });

Service worker的调控从第二回页面访问伊始

在第三回加载页面时,全体财富都是从网络载的,Service worker 在第壹遍加载时不会收获调节网络响应,它只会在连续访问页面时起效果。

澳门新萄京官方网站 16

页面第一遍加载时成功install,并进入idle状态。

澳门新萄京官方网站 17

页面第三回加载时,进入activated状态,希图处理全部的风浪,同时 浏览器会向服务器发送2个异步 请求来检查Service worker作者是或不是有新的本子,构成了Service worker的翻新机制。

澳门新萄京官方网站 18

Service worker拍卖完全部的事件后,进入idle状态,最终进入terminated状态财富被假释,当有新的轩然大波时有爆发时再也被调用。

如何缓存和再次回到Request

您早就设置了service worker,你今后得以重临您缓存的伏乞了。

当service worker被设置成功还要用户浏览了另一个页面大概刷新了近些日子的页面,service worker将起来收受到fetch事件。上面是1个例证:

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里,大家传入了2个由caches.match发生的promise.caches.match 查找request中被service worker缓存命中的response。

借使大家有1个命中的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只好被读取三次,所以我们得将它克隆出来,1份发给浏览器,一份发给缓存。

开辟者工具

Chrome浏览器提供了一种类的工具来支持你来调整ServiceWorker,日志也会平素突显在调整台上。

你最好应用匿超方式来拓张开荒专门的工作,那样能够清除缓存对开垦的打扰。

最后,Chrome的Lighthouse扩张也可以为您的渐进式Web应用提供一些创新音讯。

特点

  • 浏览器

谷歌(Google) Chrome,Firefox,Opera以及境内的各个双核浏览器都帮助,不过 safari 不协助,那么在不匡助的浏览器里Service worker不工作。

  • https

网站必须启用https来担保使用Service worker页面的安全性,开拓时localhost私下认可以为是安枕而卧的。

  • non-block

Service worker 中的 Javascript 代码必须是非阻塞的,因为 localStorage 是阻塞性,所以不该在 Service Worker 代码中利用 localStorage。

  • 独自的实施意况

Service worker运作在友好的大局蒙受中,常常也运转在投机独自的线程中。

  • 不曾绑定到特定页面

service work能决定它所加载的上上下下范围内的资源。

  • 不能够操作DOM

跟DOM所处的条件是互为隔断的。

澳门新萄京官方网站 19

  • 未有浏览页面时也能够运行

收纳系统事件,后台运转

  • 事件驱动,要求时运维,没有须要时就终止

按需实践,只在急需时加载到内部存款和储蓄器

  • 可升级

推行时会异步获取最新的版本

什么样创新贰个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的时候即刻施行它,那么依旧在运行的旧版本的多少就坏了。

前边大家只利用了3个缓存,叫做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);
          }
        })
      );
    })
  );
});

渐进式Web应用的要领

渐进式Web应用是壹种新的本领,所以选拔的时候料定要小心。也正是说,渐进式Web应用能够让您的网址在多少个小时内获得校勘,并且在不协助渐进式Web应用的浏览器上也不会潜移默化网站的来得。

可是大家必要思考以下几点:

兑现加速/离线

管理边界和填坑

那一节内容比较新,有那多少个待定细节。希望那①节比极快就没有须求讲了(因为标准会管理这一个难点——译者注),不过今后,那一个内容照旧应当被提一下。

URL隐藏

当您的运用就是2个单U大切诺基L的应用程序时(比如游戏),笔者建议你隐藏地址栏。除外的意况笔者并不提出你隐藏地址栏。在Manifest中,display: minimal-ui 或者 display: browser对此绝大大多景色来讲丰盛用了。

Cache

网页缓存有过多,如HTTP缓存,localStorage,sessionStorage和cacheStorage都能够灵活搭配举行缓存,但操作太繁琐,直接动用更加尖端Service worker –本文的东家。

一旦设置失利了,未有很优雅的艺术获得通报

只要3个worker被注册了,不过从未出现在chrome://inspect/#service-workers或chrome://serviceworker-internals,那么很可能因为异常而安装失败了,或者是产生了一个被拒绝的的promise给event.waitUtil。

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

缓存过大

你无法将你网址中的全部剧情缓存下来。对于小一些的网址的话缓存全部内容并不是二个主题材料,然则如果3个网址包括了上千个页面吗?很显眼不是全部人对网址中的全体内容都感兴趣。存款和储蓄是有限制的,假诺您将富有访问过的页面都缓存下来的话,缓存大小会增加额不慢。

您能够那样制定你的缓存攻略:

  • 只缓存主要的页面,举例主页,联系人页面和不久前浏览小说的页面。
  • 毫不缓存任何图片,摄像和大文件
  • 定期清理旧的缓存
  • 提供贰个“离线阅读”按键,那样用户就足以挑选要求缓存哪些内容了。

添加Service worker入口

在web app的首页加多以下代码

JavaScript

<script> if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js'); } </script>

1
2
3
4
5
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
</script>

设若浏览器援救serviceWorker就报了名它,不扶助依然好端端浏览,未有Service worker所提供的增加成效。

Service worker调节范围:
简言之情形下,将sw.js投身网址的根目录下,那样Service worker澳门新萄京官方网站:worker完毕加速,入门教程。能够调节网址有着的页面,,同理,就算把sw.js放在/my-app/sw.js那么它只可以调节my-app目录下的页面。
sw.js放在/js/目录呢?越来越好的目录结议和限量调节呢?
在注册时钦命js地方并安装限制。

JavaScript

navigator.serviceWorker.register('/js/sw.js', {scope: '/sw-test/'}).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
navigator.serviceWorker.register('/js/sw.js', {scope: '/sw-test/'}).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);
    });

fetch()近来仅援助Service Workers

fetch立即协助在页面上使用了,可是近些日子的Chrome达成,它还只协助service worker。cache API也将在在页面上被援救,但是近期结束,cache也还只可以在service worker中用。

缓存刷新

亲自去做代码中在倡导呼吁以前会先查询缓存。当用户处于离线状态时,那很好,不过假使用户处于在线状态,那她只会浏览到相比较老旧的页面。

各类财富比方图片和录像不会变动,所以一般都把那一个静态财富设置为长时间缓存。这一个能源得以直接缓存一年(3壹,53六,000秒)。在HTTP Header中,便是:

Cache-Control: max-age=31536000

1
Cache-Control: max-age=31536000

页面,CSS和本子文件大概变动的更频仍一些,所以你能够设置2个不大的缓存超时时间(贰四小时),并确定保证在用户互联网连接苏醒时再一次从服务器请求:

Cache-Control: must-revalidate, max-age=86400

1
Cache-Control: must-revalidate, max-age=86400

你也能够在历次网站发布时,通过更名的艺术强制浏览器重新请求能源。

Service worker实现

监听四个事件:

JavaScript

self.addEventListener('install', onInstall); self.addEventListener('fetch', onFetch); self.addEventListener("activate", onActivate);

1
2
3
self.addEventListener('install', onInstall);
self.addEventListener('fetch', onFetch);
self.addEventListener("activate", onActivate);

fetch()的暗中认可参数

当你接纳fetch,缺省级地区级,请求不会带上cookies等凭证,要想带上的话,须要:

JavaScript

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

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

如此设计是有理由的,它比XH逍客的在同源下暗许发送凭据,但跨域时放任凭据的平整要来得好。fetch的一颦一笑更像其余的CO奥迪Q五S请求,比方<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。

小结

至此,相信您尽管依据本文一步一步操作下来,你也足以长足把温馨的Web应用转为PWA。在转为了PWA后,借使有使用满足PWA 模型的前端控件的需要,你能够试试纯前端表格控件SpreadJS,适用于 .NET、Java 和移动端等楼台的报表控件一定不会让你失望的。

初稿链接:

1 赞 1 收藏 评论

澳门新萄京官方网站 20

install

JavaScript

////////// // Install ////////// function onInstall(event) { log('install event in progress.'); event.waitUntil(updateStaticCache()); } function updateStaticCache() { return caches .open(cacheKey('offline')) .then((cache) => { return cache.addAll(offlineResources); }) .then(() => { log('installation complete!'); }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//////////
// Install
//////////
function onInstall(event) {
  log('install event in progress.');
  event.waitUntil(updateStaticCache());
}
function updateStaticCache() {
  return caches
    .open(cacheKey('offline'))
    .then((cache) => {
      return cache.addAll(offlineResources);
    })
    .then(() => {
      log('installation complete!');
    });
}

install时将兼具符合缓存计谋的财富实行缓存。

Non-CORubiconS私下认可不帮助

暗许情形下,从第一方ULANDL跨域得到一个财富将会失败,除非对方帮忙了CO揽胜S。你能够拉长3个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.');
});

fetch

JavaScript

//////// // Fetch //////// function onFetch(event) { const request = event.request; if (shouldAlwaysFetch(request)) { event.respondWith(networkedOrOffline(request)); return; } if (shouldFetchAndCache(request)) { event.respondWith(networkedOrCached(request)); return; } event.respondWith(cachedOrNetworked(request)); } onFetch做为浏览器互连网请求的代办,根据须要回到互连网或缓存内容,若是拿到了网络内容,重回网络请求时同时进行缓存操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
////////
// Fetch
////////
function onFetch(event) {
  const request = event.request;
  if (shouldAlwaysFetch(request)) {
    event.respondWith(networkedOrOffline(request));
    return;
  }
  if (shouldFetchAndCache(request)) {
    event.respondWith(networkedOrCached(request));
    return;
  }
  event.respondWith(cachedOrNetworked(request));
}
onFetch做为浏览器网络请求的代理,根据需要返回网络或缓存内容,如果获取了网络内容,返回网络请求时同时进行缓存操作。

fetch()不依照30x重定向规范

不佳,重定向在fetch()中不会被触发,那是近些日子版本的bug;

activate

JavaScript

/////////// // Activate /////////// function onActivate(event) { log('activate event in progress.'); event.waitUntil(removeOldCache()); } function removeOldCache() { return caches .keys() .then((keys) => { return Promise.all( // We return a promise that settles when all outdated caches are deleted. keys .filter((key) => { return !key.startsWith(version); // Filter by keys that don't start with the latest version prefix. }) .map((key) => { return caches.delete(key); // Return a promise that's fulfilled when each outdated cache is deleted. }) ); }) .then(() => { log('removeOldCache completed.'); }); }

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
///////////
// Activate
///////////
function onActivate(event) {
  log('activate event in progress.');
  event.waitUntil(removeOldCache());
}
function removeOldCache() {
  return caches
    .keys()
    .then((keys) => {
      return Promise.all( // We return a promise that settles when all outdated caches are deleted.
        keys
         .filter((key) => {
           return !key.startsWith(version); // Filter by keys that don't start with the latest version prefix.
         })
         .map((key) => {
           return caches.delete(key); // Return a promise that's fulfilled when each outdated cache is deleted.
         })
      );
    })
    .then(() => {
      log('removeOldCache completed.');
    });
}

在activate时依据version值来删除过期的缓存。

拍卖响应式图片

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

在service worker中,你想要在install步骤缓存2个图纸,你有以下三种接纳:

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

相比好的方案是贰或三,因为只要把持有的图纸都给下载下来存着有一点点浪费内部存款和储蓄器。

假若你将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" />

一经我们在三个二x的体现格局下,浏览器会下载image-二x.png,假设我们离线,你能够读取从前缓存并赶回image-src.png替代,借使从前它曾经被缓存过。就算如此,由于现行反革命的形式是二x,浏览器会把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;" />

澳门新萄京官方网站 21

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

管理 Service worker

改变URL Hash的Bug

在M40版本中存在三个bug,它会让页面在改动hash的时候变成service worker截至专门的学业。

你能够在那边找到越多相关的信息: 

一定网址

  1. Google Chrome

Developer Tools->Application->Service Workers

澳门新萄京官方网站 22

在这里还有五个极度实惠的复选框:

  • Offline

效仿断网状态

  • Update on reload
    加载时更新
  • Bypass for network
    接2连叁接纳互连网内容
  1. Firefox

唯有在Settings里有3个得以在HTTP意况中动用Service worker的选项,适应于调节和测试,未有单独网址下的Service worker管理。

澳门新萄京官方网站 23

  1. Opera及别的双核浏览器同谷歌(Google) Chrome
    若果看到三个一样范围内的多个Service worker,说明Service woker更新后,而原有Service worker还向来不被terminated。

越来越多内容

此地有一部分唇亡齿寒的文书档案能够参见:

浏览器全局

看看您的浏览器里都有怎样Service worker已经存在了

  1. Google Chrome

在地址栏里输入:

JavaScript

chrome://serviceworker-internals/

1
chrome://serviceworker-internals/

能够看来已经有二多少个Serviceworker了,在此地能够手动Start让它工作,也足以Unregister卸载掉。

澳门新萄京官方网站 24

  1. Firefox

有二种方法进入Service worker管住分界面来手动Start或unregister。

  • 菜单栏,Tool->Web Developer->Service workers
  • 地点栏中输入

JavaScript

about:debugging#workers

1
about:debugging#workers

澳门新萄京官方网站 25

  1. Opera及其余双核浏览器同谷歌 Chrome

取得帮衬

借使你蒙受麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于我们及时跟进和不择手腕匡助你化解难题。

赞 2 收藏 评论

澳门新萄京官方网站 26

更多

TODO:

  • Service workers的翻新须求手动编辑version,每一趟宣布新小说时必要编写制定。
  • 使用AMP让页面渲染速度到达最高。

Ref links

Service Worker Cookbook

Is service worker ready?

Chrome service worker status page

Firefox service worker status page

MS Edge service worker status page

WebKit service worker status page

1 赞 2 收藏 评论

澳门新萄京官方网站 27

本文由澳门新萄京官方网站发布于澳门新萄京赌场网址,转载请注明出处:澳门新萄京官方网站:worker完毕加速,入门教程

关键词: