worker完成加快,创立贰个至极简单的离线页面

迈向PWA!利用serviceworker的离线访问方式

2017/02/08 · JavaScript
· PWA

正文小编: 伯乐在线 –
pangjian
。未经小编许可,禁止转发!
迎接插足伯乐在线 专栏撰稿人。

微信小程序来了,能够应用WEB技术在微信构建三个具有Native应用体验的采纳,业界相当看好那种样式。不过你们只怕不知晓,谷歌(Google)早已有像样的布署性,甚至层次更高。那就是PWA(渐进式增强WEB应用)。
PWA有以下三种特色:

  • Installablity(可安装性)
  • App Shell
  • Offline(离线能力)
  • Re-engageable(推送文告能力)

拥有那么些特点都以“优雅降级、渐进增强的”,给接济的设备更好的体验,不资助的装置也不会更差。那就和微信小程序那种不良设计的一贯不同之处。

本博客也在向着PWA的样子迈进,第③步小编选取了Offline,相当于离线能力。可以让客户在未曾互连网连接的时候仍旧可以应用一些服务。那一个能力运用了ServiceWorker技术。

万事如意思路就是,利用service
worker,另起贰个线程,用来监听全体互连网请求,讲曾经呼吁过的数码放入cache,在断网的动静下,直接取用cache里面的能源。为呼吁过的页面和图片,显示2个暗中同意值。当有网络的时候,再重复从服务器更新。
皇家赌场手机版 1
代码那里就不贴了,今后大概会特地写一篇来详细介绍ServiceWorker,有趣味的能够直接参考源码。
挂号起来也相当便利

JavaScript

// ServiceWorker_js (function() { ‘use strict’;
navigator.serviceWorker.register(‘/sw.js’, {scope:
‘/’}).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
10
11
12
// ServiceWorker_js
(function() {
    ‘use strict’;
    navigator.serviceWorker.register(‘/sw.js’, {scope: ‘/’}).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);
    });
 
})();

此地须求专注的是,sw.js所在的目录要超越它的决定范围,也等于scope。我把sw.js置身了根目录来控制总体目录。

接下去看看大家的终极效果呢,你也足以在团结的浏览器下断网尝试一下。当然有局地浏览器近日还不扶助,比如有名的Safari。

行使 Service worker 创设1个十一分简单的离线页面

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

本文由 伯乐在线 –
刘健超-J.c
翻译,艾凌风
校稿。未经许可,禁止转发!
英文出处:Dean
Hume。欢迎参预worker完成加快,创立贰个至极简单的离线页面。翻译组。

让我们想像以下场景:大家那时候在一辆通往农村的列车上,用运动设备望着一篇很棒的小说。与此同时,当您点击“查看越来越多”的链接时,高铁忽然进入了隧道,导致运动装备失去了网络,而
web 页面会显示出类似以下的内容:

皇家赌场手机版 2

那是格外令人寒心的体会!幸运的是,web
开发者们能通过有个别新特征来改革那类的用户体验。小编近年径直在折腾 ServiceWorkers,它给 web 带来的无尽恐怕性总能给自家惊喜。Service Workers
的上佳特质之一是允许你检测网络请求的场所,并让你作出相应的响应。

在那篇小说里,我打算用此本性检查用户的脚下网络连接情状,如若没连接则赶回2个极品不难的离线页面。即使那是二个老大基础的案例,但它能给你带来启发,让您知道运行并运维该性格是何等的差不离!假诺您没精通过
Service Worker,小编提议你看看此 Github
repo,明白更加多相关的音讯。

在该案例开头前,让大家先不难地看望它的办事流程:

  1. 在用户第一回访问我们的页面时,我们会设置 ServiceWorker,并向浏览器的缓存添加大家的离线 HTML 页面
  2. 下一场,假诺用户打算导航到另一个 web
    页面(同一个网站下),但那时已断网,那么我们将回到已被缓存的离线
    HTML 页面
  3. 唯独,即使用户打算导航到别的三个 web
    页面,而那时候网络已接连,则能照常浏览页面

运用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应用一般所不具有的富离线体验,定时的沉默更新,音信文告推送等功用。而新的Serviceworkers标准让在Web App上有所那个职能成为大概。

离线有缓存意况

皇家赌场手机版 3

让我们开头吧

要是你有以下 HTML 页面。那就算十二分基础,但能给你完整思路。

XHTML

<!DOCTYPE html>

1
<!DOCTYPE html>

继之,让我们在页面里登记 瑟维斯 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(‘ServiceWorker 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 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 Worker
时,向缓存添加了离线页面。如果我们将代码分为几小块,可观察前几行代码中,我为离线页面内定了缓存版本和UMuranoL。借使你的缓存有两样版本,那么您只需立异版本号即可简单地消除缓存。在大致在第32
行代码,作者向那些离线页面及其财富(如:图片)发出请求。在赢得成功的响应后,大家将离线页面和相关财富充裕到缓存。

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

JavaScript

this.add伊夫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 访问互联网)

皇家赌场手机版 4

万一您刷新页面,你应有能观望相应的离线页面!

皇家赌场手机版 5

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

自家明白用在此案例中的页面很简短,但你的离线页面则取决于你本身!如果你想长远该案例的故事情节,你可以为离线页面添加缓存破坏(
cache busting),如:
此案例。

加快/离线访问只需三步

  • 首页添加注册代码

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都引用了何等第2方能源,各种加到忽略列表里。

皇家赌场手机版 6

在根目录下添加offline.html,在一直不互联网且缓存中也从猴时使用,效果如下:

皇家赌场手机版 7

在根目录下添加offline.svg,在无互联网时图片财富请求再次回到该公文。

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是1个可编程的互联网代理,允许开发者控制页面上处理的互联网请求。
  • 在不被运用的时候,它会融洽终止,而当它再一次被用到的时候,会被再度激活,所以您无法凭借于service
    worker的onfecth和onmessage的处理函数中的全局状态。假如你想要保存一些持久化的新闻,你可以在service
    worker里使用IndexedDB API。
  • Serviceworker多量使用promise,所以一旦你不打听哪些是promise,那您必要先读书worker完成加快,创立贰个至极简单的离线页面。这篇文章。

离线无缓存情状

会显示壹个默许的页面

皇家赌场手机版 8

-EOF-

打赏扶助本身写出越多好文章,谢谢!

打赏小编

开展阅读

其它,还有多少个很棒的离线作用案例。如:Guardian 营造了一个持有 crossword
puzzle(填字游戏)的离线
web 页面 –
由此,固然等待互联网重连时(即已在离线状态下),也能找到一点乐趣。小编也推荐看看
Google Chrome Github
repo,它包涵了诸多不比的
Service Worker 案例 – 其中有的运用案例也在那!

然则,假诺您想跳过上述代码,只是想大致地通过2个库来处理有关操作,那么自身推荐您看看
UpUp。那是1个轻量的台本,能让你更自在地采纳离线功效。

打赏帮助本人翻译更加多好作品,多谢!

打赏译者

增速效果

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

皇家赌场手机版 9

基于webpagetest

查看测试结果

Service Worker的生命周期

Service worker拥有三个一心独立于Web页面的生命周期。

要让三个service
worker在你的网站上生效,你须求先在您的网页中登记它。注册1个service
worker之后,浏览器会在后台默默运维3个service worker的安装进度。

在装置进程中,浏览器会加载并缓存一些静态财富。假设全数的文本被缓存成功,service
worker就安装成功了。若是有任何公文加载或缓存失利,那么安装进程就会破产,service
worker就不大概被激活(也即没能安装成功)。纵然暴发如此的难题,别担心,它会在下次再品尝安装。

当安装到位后,service
worker的下一步是激活,在这一等级,你还足以荣升1个service
worker的版本,具体内容我们会在前面讲到。

在激活之后,service
worker将接管全数在自身管辖域范围内的页面,不过假如二个页面是刚刚注册了service
worker,那么它这几遍不会被接管,到下两次加载页面的时候,service
worker才会生效。

当service
worker接管了页面之后,它恐怕有二种意况:要么被为止以节外省存,要么会处理fetch和message事件,那多个事件分别发出于2个网络请求出现依旧页面上发送了二个音讯。

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

皇家赌场手机版 10

打赏支持小编写出越来越多好文章,多谢!

任选一种支付办法

皇家赌场手机版 11
皇家赌场手机版 12

1 赞 1 收藏
评论

打赏帮忙本人翻译越来越多好小说,感谢!

任选一种支付办法

皇家赌场手机版 13
皇家赌场手机版 14

1 赞 3 收藏 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得到一个TLS证书。不一样的server安装方法差距,阅读辅助文档并透过Mozilla’s
SSL config
generator刺探最佳实践。

有关我:pangjian

皇家赌场手机版 15

庞健,金融IT男。
个人主页 ·
作者的篇章 ·
5 ·
  

皇家赌场手机版 16

至于我:刘健超-J.c

皇家赌场手机版 17

前端,在路上…
个人主页 ·
作者的稿子 ·
19 ·
    

皇家赌场手机版 18

什么是 Service worker

皇家赌场手机版 19

如上图,Service
worker

是一种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当2个页面注册了八个
Service
worker
,它就足以注册一比比皆是事件处理器来响应如互联网请求和新闻推送那些事件。Service
worker

能够被用来管理缓存,当响应八个互联网请求时方可配备为回去缓存照旧从网络获取。由于Service
worker

是依照事件的,所以它只在拍卖这么些事件的时候被调入内存,不用担心常驻内存占用财富导致系统变慢。

使用Service Worker

方今大家有了polyfill,并且消除了HTTPS,让大家看看到底怎么用service
worker。

Service worker生命周期

皇家赌场手机版 20

Service
worker

为网页添加1个看似于APP的生命周期,它只会响应系统事件,固然浏览器关闭时操作系统也足以唤起Service
worker
,这一点尤其重要,让web
app与native app的能力变得就像了。

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

一旦Service
worker
地处activated状态,就可以完全控制应用的能源,对互联网请求进行自作者批评,修改互连网请求,从互联网上取得并再次来到内容大概再次来到由已设置的Service
worker
预示获取并缓存好的财富,甚至还足以生成内容并再次来到给网络语法。

抱有的那个都用户都是晶莹的,事实上,1个设计能够的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是否对你的网站启用了。

皇家赌场手机版 21

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

你会意识那么些成效可以很方便地在二个效仿窗口中测试你的service
worker,那样您可以关闭和另行打开它,而不会影响到您的新窗口。任何创造在模仿窗口中的注册服务和缓存在窗口被关门时都将化为乌有。

Service worker的支配从第②遍页面访问开首

在首回加载页面时,全部财富都以从网络载的,Service
worker

在第一回加载时不会收获控制互连网响应,它只会在此起彼伏访问页面时起效果。

皇家赌场手机版 22

页面首回加载时成功install,并跻身idle状态。

皇家赌场手机版 23

页面第二回加载时,进入activated状态,准备处理全部的轩然大波,同时
浏览器会向服务器发送八个异步 请求来检查Service
worker
本人是或不是有新的本子,构成了Service
worker
的换代机制。

皇家赌场手机版 24

Service
worker
拍卖完全数的风浪后,进入idle状态,最后进入terminated状态财富被释放,当有新的风浪爆发时再度被调用。

瑟维斯 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得到3个promise并使用它来博取安装花费的时间以及是或不是安装成功。

只要拥有的文件都被缓存成功了,那么service
worker就设置成功了。如果其余二个文书下载战败,那么安装步骤就会破产。那么些主意允许你依靠于您自个儿钦定的保有能源,但是那意味着你需求非凡谨慎地决定怎么着文件须求在装置步骤中被缓存。内定了太多的文本的话,就会大增设置战败率。

上面只是3个粗略的例子,你可以在install事件中执行其余操作还是甚至忽视install事件。

特点

  • 浏览器

谷歌(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所处的条件是互相隔离的。

皇家赌场手机版 25

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

采用系统事件,后台运转

  • 事件驱动,须要时运转,不须求时就截止

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

  • 可升级

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

何以缓存和再次回到Request

你已经安装了service worker,你以后得以回来您缓存的哀求了。

当service
worker被装置成功还要用户浏览了另3个页面或然刷新了当下的页面,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里,我们传入了3个由caches.match暴发的promise.caches.match
查找request中被service worker缓存命中的response。

假若大家有一个命中的response,大家回到被缓存的值,否则大家重回2个实时从互联网请求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. 丰硕3个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);
    });

即便设置失利了,没有很优雅的格局获取通报

倘若3个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 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’
})

如此那般设计是有理由的,它比XH奥迪Q3的在同源下默许发送凭据,但跨域时放任凭据的条条框框要来得好。fetch的行为更像别的的CO帕杰罗S请求,例如<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-CO汉兰达S暗中同意不扶助

暗许情形下,从第贰方UXC60L跨域拿到一个财富将会退步,除非对方帮助了CO奥德赛S。你可以添加三个non-CO奔驰G级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.’);
});

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步骤缓存3个图形,你有以下二种选用:

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

若是我们在2个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;" />

皇家赌场手机版 26

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

一定网站

  1. Google Chrome

Developer Tools->Application->Service Workers

皇家赌场手机版 27

在那里还有三个越发有效的复选框:

  • Offline

宪章断网状态

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

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

皇家赌场手机版 28

  1. Opera及其他双核浏览器同谷歌(Google) Chrome
    比方见到多个一律范围内的三个Service
    worker
    ,说明Service
    woker
    更新后,而原有Service
    worker
    还并未被terminated。

改变URL Hash的Bug

在M40版本中设有多个bug,它会让页面在变更hash的时候造成service
worker截止工作。

您可以在那边找到越多相关的音讯: 

浏览器全局

探访你的浏览器里都有何Service worker已经存在了

  1. Google Chrome

在地址栏里输入:

JavaScript

皇家赌场手机版,chrome://serviceworker-internals/

1
chrome://serviceworker-internals/

可以看来曾经有二十五个Serviceworker了,在此处能够手动Start让它工作,也可以Unregister卸载掉。

皇家赌场手机版 29

  1. Firefox

有二种艺术进入Service
worker
管理界面来手动Start或unregister。

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

JavaScript

about:debugging#workers

1
about:debugging#workers

皇家赌场手机版 30

  1. Opera及任何双核浏览器同谷歌(Google) Chrome

越多内容

此间有一些有关的文档可以参见:

更多

TODO:

  • Service
    workers
    的更新需求手动编辑version,每一遍公布新小说时须求编制。
  • 使用AMP让页面渲染速度高达最高。

赢得扶持

比方您赶上麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于大家登时跟进和不择手段资助您化解难题。

赞 2 收藏
评论

皇家赌场手机版 31

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

皇家赌场手机版 32

Leave a Comment.