创建一个极度简单的离线页面,大不列颠及北爱尔兰联合王国卫报的个性离线页面是如此做的

利用Service(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入门

2015/03/26 · JavaScript
· Service Worker

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

  • 十年踪迹]()   

原生App拥有Web应用普通所不抱有的富离线体验,定时的沉默更新,音信布告推送等作用。而新的瑟维斯(Service)workers标准让在Web App上具有这么些作用成为可能。

使用 Service worker 成立一个非凡简单的离线页面

2016/06/07 · JavaScript
· 1 评论 · Service
Worker

本文由 伯乐在线 –
刘健超-J.c
翻译,艾凌风
校稿。未经许可,禁止转发!
英文出处:Dean
Hume。欢迎参与翻译组。

让我们想像以下场景:我们那时候在一辆通往农村的列车上,用移动设备看着一篇很棒的篇章。与此同时,当你点击“查看更加多”的链接时,火车忽然进入了隧道,导致运动装备失去了网络,而
web 页面会显示出类似以下的情节:

亚洲必赢官网 1

那是一定令人心寒的体会!幸运的是,web
开发者们能通过有些新特点来改进那类的用户体验。我近期直接在折腾 Service(Service)Workers,它给 web 带来的无尽可能性总能给本人惊喜。瑟维斯(Service) Workers
的绝妙特质之一是同意你检测网络请求的气象,并让您作出相应的响应。

在这篇小说里,我打算用此特性检查用户的当前网络连接情形,假设没连接则赶回一个最佳不难的离线页面。即便那是一个老大基础的案例,但它能给您带来启迪,让你知道启动并运行该特性是何等的简易!若是您没领会过
Service Worker,我指出你看看此 创建一个极度简单的离线页面,大不列颠及北爱尔兰联合王国卫报的个性离线页面是如此做的。Github
repo,精通愈来愈多相关的音讯。

在此案例开端前,让我们先不难地看望它的办事流程:

  1. 在用户首次访问大家的页面时,大家会设置 Service(Service)Worker,并向浏览器的缓存添加大家的离线 HTML 页面
  2. 然后,若是用户打算导航到另一个 web
    页面(同一个网站下),但此时已断网,那么大家将再次回到已被缓存的离线
    HTML 页面
  3. 只是,假设用户打算导航到其余一个 web
    页面,而那时网络已一而再,则能照常浏览页面

连不上网?大英帝国卫报的本性离线页面是那样做的

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

本文由 伯乐在线 –
Erucy
翻译,weavewillg
校稿。未经许可,禁止转载!
英文出处:Oliver
Ash。欢迎插手翻译组。

我们是怎么着行使 service worker 来为 theguardian.com
构建一个自定义的离线页面。

亚洲必赢官网 2

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

您正在朝着公司途中的大巴里,在手机上打开了
Guardian
应用。客车被隧道包围着,然而那个利用可以正常运行,即使没有网络连接,你也能收获完全的机能,除了出示的内容可能有点旧。如若你品味在网站上也这么干,可惜它完全没办法加载:

亚洲必赢官网 3

安卓版 Chrome 的离线页面

Chrome 中的那些彩蛋,很两个人都不晓得》

Chrome
在离线页面上有个藏匿的嬉戏(桌面版上按空格键,手机版上点击那只恐龙),那有些能减轻一点您的抑郁。可是我们可以做得更好。

Service
workers
允许网站小编拦截自己站点的装有网络请求,那也就意味着大家得以提供完善的离线体验,就如原生应用相同。在
Guardian
网站,大家近日上线了一个自定义的离线体验效果。当用户离线的时候,他们会合到一个包罗Guardian
标识的页面,上边带有一个简练的离线提示,还有一个填字游戏,他们得以在等待网络连接的时候玩玩这些找点乐子。这篇博客解释了大家是哪些构建它的,可是在始发从前,你可以先自己试试看。

加速/离线访问只需三步

  • 首页添加注册代码

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都引用了怎么第三方资源,逐个加到忽略列表里。

亚洲必赢官网 4

在根目录下添加offline.html,在没有网络且缓存中也并龙时利用,效果如下:

亚洲必赢官网 5

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

Service Worker 是什么?

一个 service worker
是一段运行在浏览器后台进程里的脚本,它独自于近日页面,提供了那么些不需求与web页面交互的机能在网页背后悄悄执行的能力。在以后,基于它可以兑现音信推送,静默更新以及地理围栏等劳动,不过当前它首先要享有的作用是阻挡和拍卖网络请求,包蕴可编程的响应缓存管理。

干什么说这么些API是一个不行棒的API呢?因为它使得开发者可以协助越发好的离线体验,它赋予开发者完全控制离线数据的能力。

在service worker提议往日,别的一个提供开发者离线体验的API叫做App
Cache。但是App
Cache有些局限性,例如它可以很不难地化解单页应用的题目,可是在多页应用上会很麻烦,而Service(Service)workers的面世正是为通晓决App Cache的痛点。

上面详细说一下service worker有怎样要求专注的地方:

  • 它是JavaScript
    Worker,所以它不可能间接操作DOM。然而service
    worker能够因此postMessage与页面之间通信,把信息公告给页面,若是需求的话,让页面自己去操作DOM。
  • 瑟维斯(Service)(Service)worker是一个可编程的网络代理,允许开发者控制页面上处理的网络请求。
  • 在不被使用的时候,它会协调终止,而当它再也被用到的时候,会被再度激活,所以你无法借助于service
    worker的onfecth和onmessage的处理函数中的全局状态。若是您想要保存一些持久化的新闻,你可以在service
    worker里使用IndexedDB API。
  • 亚洲必赢官网,瑟维斯(Service)(Service)worker大批量使用promise,所以即便你不通晓什么是promise,那您需求先读书这篇文章。

让我们早先吧

一经你有以下 HTML 页面。那固然这些基础,但能给你完整思路。

XHTML

<!DOCTYPE html>

1
<!DOCTYPE html>

进而,让我们在页面里登记 瑟维斯(Service)(Service) Worker,那里仅创立了该对象。向正要的
HTML 里添加以下代码。

JavaScript

<script> // Register the service worker // 注册 service worker if
(‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/service-worker.js’).then(function(registration)
{ // Registration was successful // 注册成功 console.log(‘ServiceWorker
registration successful with scope: ‘, registration.scope);
}).catch(function(err) { // registration failed 🙁 // 注册失利 🙁
console.log(‘Service(Service)Worker registration failed: ‘, err); }); }
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
// Register the service worker
// 注册 service worker
if (‘serviceWorker’ in navigator) {
    navigator.serviceWorker.register(‘/service-worker.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);
   });
}
</script>

下一场,咱们须要创制 Service Worker 文件并将其取名为
‘service-worker.js‘。大家打算用这一个 瑟维斯(Service)(Service) Worker
拦截任何网络请求,以此检查网络的连接性,并依据检查结果向用户重返最适合的情节。

JavaScript

‘use strict’; var cacheVersion = 1; var currentCache = { offline:
‘offline-cache’ + cacheVersion }; const offlineUrl =
‘offline-page.html’; this.addEventListener(‘install’, event => {
event.waitUntil( caches.open(currentCache.offline).then(function(cache)
{ return cache.addAll([ ‘./img/offline.svg’, offlineUrl ]); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
‘use strict’;
 
var cacheVersion = 1;
var currentCache = {
  offline: ‘offline-cache’ + cacheVersion
};
const offlineUrl = ‘offline-page.html’;
 
this.addEventListener(‘install’, event => {
  event.waitUntil(
    caches.open(currentCache.offline).then(function(cache) {
      return cache.addAll([
          ‘./img/offline.svg’,
          offlineUrl
      ]);
    })
  );
});

在地点的代码中,大家在设置 Service(Service) Worker
时,向缓存添加了离线页面。假若大家将代码分为几小块,可知到前几行代码中,我为离线页面指定了缓存版本和URL。若是您的缓存有两样版本,那么你只需革新版本号即可不难地排除缓存。在大约在第
12
行代码,我向这些离线页面及其资源(如:图片)发出请求。在得到成功的响应后,我们将离线页面和有关资源丰裕到缓存。

当今,离线页面已存进缓存了,我们可在须求的时候检索它。在同一个 ServiceWorker 中,我们要求对无网络时回来的离线页面添加相应的逻辑代码。

JavaScript

this.add伊芙(Eve)ntListener(‘fetch’, event => { // request.mode = navigate
isn’t supported in all browsers // request.mode = naivgate
并从未获取所有浏览器的支撑 // so include a check for Accept: text/html
header. // 因而对 header 的 Accept:text/html 举办把关 if
(event.request.mode === ‘navigate’ || (event.request.method === ‘GET’ &&
event.request.headers.get(‘accept’).includes(‘text/html’))) {
event.respondWith( fetch(event.request.url).catch(error => { //
Return the offline page // 再次来到离线页面 return caches.match(offlineUrl);
}) ); } else{ // Respond with everything else if we can //
重返任何我们能回来的东西 event.respondWith(caches.match(event.request)
.then(function (response) { return response || fetch(event.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
this.addEventListener(‘fetch’, event => {
  // request.mode = navigate isn’t supported in all browsers
  // request.mode = naivgate 并没有得到所有浏览器的支持
  // so include a check for Accept: text/html header.
  // 因此对 header 的 Accept:text/html 进行核实
  if (event.request.mode === ‘navigate’ || (event.request.method === ‘GET’ && event.request.headers.get(‘accept’).includes(‘text/html’))) {
        event.respondWith(
          fetch(event.request.url).catch(error => {
              // Return the offline page
              // 返回离线页面
              return caches.match(offlineUrl);
          })
    );
  }
  else{
        // Respond with everything else if we can
        // 返回任何我们能返回的东西
        event.respondWith(caches.match(event.request)
                        .then(function (response) {
                        return response || fetch(event.request);
                    })
            );
      }
});

为了测试该功用,你可以行使 Chrome
内置的开发者工具。首先,导航到你的页面,然后假如设置上了 ServiceWorker,就打开 Network 标签并将节流(throttling)改为
Offline。(译者注:若将节流设置为 Offline
没效果,则可经过关闭网络或者通过360广安警卫禁止 Chrome 访问网络)

亚洲必赢官网 6

假诺你刷新页面,你应当能收占卜应的离线页面!

亚洲必赢官网 7

假如你只想大约地测试该意义而不想写任何代码,那么你可以访问我已开立好的
demo。别的,上述总体代码可以在
Github repo 找到。

自我驾驭用在此案例中的页面很粗略,但你的离线页面则取决于你协调!要是你想浓厚该案例的始末,你可以为离线页面添加缓存破坏(
cache busting),如:
此案例。

试试看

你要求一个支撑 Service
Worker 和 fetch
API 的浏览器。截至到本文编写时唯有Chrome(手机版和桌面版)同时协理那二种 API(译者注:Opera
近期也支撑那两者),但是 Firefox
很快就要支持了(在每一日更新的本子中曾经支撑了),除此之外 Safari
之外的享有浏览器也都在摸索。其余,service worker 只好登记在拔取了
HTTPS 的网站上,theguardian.com
已经开端逐渐搬迁到 HTTPS,所以大家不得不在网站的 HTTPS
部分提供离线体验。就近来的话,我们选拔了 开发者博客 作为大家用来测试的地点。所以一旦你是在大家网站的 开发者博客 部分阅读那篇作品的话,很幸运。

当你使用帮衬的浏览器访问我们的 开发者博客 中的页面的时候,一切就准备妥当了。断开你的网络连接,然后刷新一下页面。若是您自己没规范尝试的话,可以看一下那段 示范视频(译者注:需梯子)。

加紧效果

首页加快后,网络请求从16降为1,加载时间从2.296s降为0.654s,获得了一下加载的结果。

亚洲必赢官网 8

基于webpagetest

查看测试结果

瑟维斯(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初次安装的生命周期:

亚洲必赢官网 9

举办阅读

别的,还有几个很棒的离线作用案例。如:Guardian 构建了一个持有 crossword
puzzle(填字游戏)的离线
web 页面 –
因而,即便等待网络重连时(即已在离线状态下),也能找到一点乐趣。我也援引看看
Google Chrome Github
repo,它含有了诸多差其余Service Worker 案例 – 其中有的施用案例也在那!

可是,假设你想跳过上述代码,只是想差不多地通过一个库来拍卖相关操作,那么自己引进您看看
UpUp。那是一个轻量的脚本,能让您更自在地选择离线功用。

打赏援救自己翻译更加多好小说,谢谢!

打赏译者

干活规律

经过一段简单的
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)(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,你会看到专门为你订制的个性化内容,它们是在您后面访问网站时由浏览器缓存下来的。它在设置进程中也不会发生其余困难,你所需求的只是访问那么些网站而已,不像原生应用,还亟需用户有一个行使商店的账号才能安装。Serviceworker
同样可以扶持大家进步网站的加载速度,因为网站的框架可以被有限协理地缓存下来,似乎原生应用相同。

若是您对 service worker
很感兴趣,想要通晓更加多内容的话,开发者 Matt
Gaunt(Chrome的一寸丹心扶助者)写了一篇越发详细地 介绍 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精晓最佳实践。

打赏帮忙自己翻译越多好文章,谢谢!

任选一种支付格局

亚洲必赢官网 10
亚洲必赢官网 11

1 赞 3 收藏 1
评论

打赏帮助自己翻译更加多好小说,谢谢!

亚洲必赢官网 12

1 赞 收藏
评论

什么是 Service worker

亚洲必赢官网 13

如上图,Service
worker

是一种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当一个页面注册了一个
Service
worker
,它就足以登记一系列事件处理器来响应如网络请求和信息推送那几个事件。Service
worker

可以被用来治本缓存,当响应一个网络请求时可以布署为回到缓存如故从网络得到。由于Service
worker

是根据事件的,所以它只在拍卖那么些事件的时候被调入内存,不用担心常驻内存占用资源导致系统变慢。

使用Service Worker

今天大家有了polyfill,并且搞定了HTTPS,让大家看看到底怎么用service
worker。

有关作者:刘健超-J.c

亚洲必赢官网 14

前端,在路上…
个人主页 ·
我的篇章 ·
19 ·
    

亚洲必赢官网 15

至于作者:Erucy

亚洲必赢官网 16

曾经的SharePoint喵星程序猿(暂时还挂着微软MVP的名头),现在的Azure/.Net/MongoDB/Cordova/前端程序猿,偶尔写小说
个人主页 ·
我的小说 ·
46 ·
  

亚洲必赢官网 17

瑟维斯(Service)(Service) worker生命周期

亚洲必赢官网 18

Service
worker

为网页添加一个类似于APP的生命周期,它只会响应系统事件,固然浏览器关闭时操作系统也可以提示Service
worker
,这一点更加重要,让web
app与native app的能力变得好像了。

Service
worker
在Register时会触发Install事件,在Install时方可用来预先获取和缓存应用所需的资源并设置每个文件的缓存策略。

一旦Service
worker
居于activated状态,就足以完全控制应用的资源,对网络请求举行自我批评,修改网络请求,从网络上赢得并赶回内容可能重回由已安装的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是否对你的网站启用了。

亚洲必赢官网 19

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

您会发现那些意义可以很便利地在一个模仿窗口中测试你的service
worker,这样您可以关闭和重复打开它,而不会影响到您的新窗口。任何创设在模拟窗口中的注册服务和缓存在窗口被关闭时都将断线风筝。

瑟维斯(Service) worker的控制从第二次页面访问发轫

在首次加载页面时,所有资源都是从网络载的,Service
worker

在首次加载时不会拿走控制网络响应,它只会在接二连三访问页面时起效果。

亚洲必赢官网 20

页面首次加载时成功install,并进入idle状态。

亚洲必赢官网 21

页面第二次加载时,进入activated状态,准备处理所有的轩然大波,同时
浏览器会向服务器发送一个异步 请求来检查Service
worker
自己是或不是有新的版本,构成了Service
worker
的更新机制。

亚洲必赢官网 22

Service
worker
拍卖完所有的风浪后,进入idle状态,最终进入terminated状态资源被保释,当有新的事件暴发时再一次被调用。

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事件。

特点

  • 浏览器

谷歌(Google) Chrome,Firefox,Opera以及国内的各个双核浏览器都援救,但是 safari
不援助,那么在不匡助的浏览器里Service
worker
不工作。

  • https

网站必须启用https来确保使用Service
worker
页面的安全性,开发时localhost默许认为是高枕无忧的。

  • non-block

Service
worker

中的 Javascript 代码必须是非阻塞的,因为 localStorage
是阻塞性,所以不应当在 Service(Service) Worker 代码中动用 localStorage。

  • 独自的实践环境

Service
worker
运作在团结的大局环境中,日常也运行在团结独自的线程中。

  • 不曾绑定到特定页面

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

  • 不可能操作DOM

跟DOM所处的条件是相互隔离的。

亚洲必赢官网 23

  • 未曾浏览页面时也得以运行

接收系统事件,后台运行

  • 事件驱动,须求时运行,不必要时就告一段落

按需举办,只在须要时加载到内存

  • 可升级

施行时会异步获取最新的本子

如何缓存和再次回到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只可以被读取一回,所以大家得将它克隆出来,一份发给浏览器,一份发给缓存。

落到实处加快/离线

怎么立异一个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);
          }
        })
      );
    })
  );
});

Cache

网页缓存有众多,如HTTP缓存,localStorage,sessionStorage和cacheStorage都可以灵活搭配举行缓存,但操作太繁琐,直接动用更尖端Service
worker

–本文的主人公。

拍卖边界和填坑

这一节内容比较新,有很多待定细节。希望这一节很快就不需要讲了(因为标准会处理这个题材——译者注),可是现在,这一个内容如故应当被提一下。

添加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
可以决定网站有着的页面,,同理,若是把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);
    });

只要设置失利了,没有很优雅的主意获取通报

设若一个worker被登记了,不过没有出现在chrome://inspect/#service-workers或chrome://serviceworker-internals,那么很可能因为异常而安装失败了,或者是产生了一个被拒绝的的promise给event.waitUtil。

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

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()近来仅支持瑟维斯(Service)(Service) Workers

fetch马上匡助在页面上采用了,但是当前的Chrome完毕,它还只协理service
worker。cache
API也即将在页面上被帮忙,但是近日为止,cache也还不得不在service
worker中用。

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时将所有符合缓存策略的资源进行缓存。

fetch()的默许参数

当您利用fetch,缺省地,请求不会带上cookies等证据,要想带上的话,须要:

JavaScript

fetch(url, { credentials: ‘include’ })

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

那样设计是有理由的,它比XHR的在同源下默许发送凭据,但跨域时放弃凭据的条条框框要来得好。fetch的表现更像其他的CORS请求,例如<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。

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做为浏览器网络请求的代理,根据需要返回网络或缓存内容,如果获取了网络内容,返回网络请求时同时进行缓存操作。

Non-CORS默许不匡助

默许意况下,从第三方URL跨域得到一个资源将会破产,除非对方协助了CORS。你可以添加一个non-CORS选项到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.’);
});

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值来删除过期的缓存。

fetch()不根据30x重定向规范

糟糕,重定向在fetch()中不会被触发,这是时下版本的bug;

管理 Service worker

拍卖响应式图片

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;" />

亚洲必赢官网 24

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

特定网站

  1. Google Chrome

Developer Tools->Application->Service Workers

亚洲必赢官网 25

在那里还有多少个更加有效的复选框:

  • Offline

上行下效断网状态

  • Update on reload
    加载时更新
  • Bypass for network
    连日选用网络内容
  1. Firefox

除非在Settings里有一个足以在HTTP环境中利用Service
worker
的选项,适应于调试,没有单独网站下的Service
worker
管理。

亚洲必赢官网 26

  1. Opera及别的双核浏览器同谷歌 Chrome
    假若看到多少个相同范围内的多个Service
    worker
    ,说明Service
    woker
    更新后,而原有Service
    worker
    还尚未被terminated。

改变URL Hash的Bug

在M40版本中留存一个bug,它会让页面在转移hash的时候造成service
worker甘休工作。

您可以在此处找到越来越多相关的信息: 

浏览器全局

看望您的浏览器里都有哪些瑟维斯(Service)(Service) worker已经存在了

  1. Google Chrome

在地址栏里输入:

JavaScript

chrome://serviceworker-internals/

1
chrome://serviceworker-internals/

能够见见曾经有24个瑟维斯(Service)(Service)worker了,在此处可以手动Start让它工作,也得以Unregister卸载掉。

亚洲必赢官网 27

  1. Firefox

有三种格局进入Service
worker
管制界面来手动Start或unregister。

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

JavaScript

about:debugging#workers

1
about:debugging#workers

亚洲必赢官网 28

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

更加多内容

那边有局地相关的文档可以参见:

更多

TODO:

  • Service
    workers
    的创新需要手动编辑version,每便发布新小说时索要编制。
  • 使用AMP让页面渲染速度直达最高。

获得扶持

假诺您遇见麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于我们当下跟进和尽可能帮衬您解决问题。

赞 2 收藏
评论

亚洲必赢官网 29

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 收藏
评论

亚洲必赢官网 30

网站地图xml地图