利用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上富有这个功用成为可能。

加速/离线访谈只需三步

  • 首页增多注册代码

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都援用了什么第三方资源,各种加到忽视列表里。

澳门十大娱乐网址大全 1

在根目录下增添offline.html,在未有网络且缓存中也从不经常利用,效果如下:

澳门十大娱乐网址大全 2

在根目录下加多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是贰个可编制程序的互联网代理,允许开荒者控制页面上拍卖的网络须求。
  • 在不被应用的时候,它会融洽终止,而当它再也被用到的时候,会被再次激活,所以您无法依赖于service
    worker的onfecth和onmessage的管理函数中的全局状态。要是你想要保存一些持久化的消息,你能够在service
    worker里使用IndexedDB API。
  • Serviceworker多量使用promise,所以假如您不打听怎样是promise,那你须求先读书这篇文章。

加快效果

首页加速后,网络乞求从16降为1,加载时间从2.296s降为0.654s,获得了眨眼间间加载的结果。

澳门十大娱乐网址大全 3

基于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初次安装的生命周期:

澳门十大娱乐网址大全 4

加快/离线原理探寻

在我们开始写码在此之前

从这个体系地址拿到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摸底最好施行。

什么是 Service worker

澳门十大娱乐网址大全 5

如上图,Service
worker

是大器晚成种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当二个页面注册了三个
Service
worker
,它就可以登记黄金时代种种事件微型机来响应如网络央浼和音讯推送这个事件。Service
worker

能够被用来治本缓存,当响应二个网络伏乞时能够配备为回去缓存依然从网络获取。由于Service
worker

是依赖事件的,所以它只在管理这几个事件的时候被调入内部存款和储蓄器,不用顾忌常驻内部存款和储蓄器占用财富招致系统变慢。

使用Service Worker

现行反革命大家有了polyfill,况兼化解了HTTPS,让我们看见到底怎么用service
worker。

Service worker生命周期

澳门十大娱乐网址大全 6

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是否对你的网站启用了。

澳门十大娱乐网址大全 7

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

您会意识那些功用能够很有利地在一个模仿窗口中测量试验你的service
worker,那样你能够关闭和重复展开它,而不会潜移默化到您的新窗口。任何创立在模仿窗口中的注册服务和缓存在窗口被关门时都将秋风落叶。

Service worker的垄断(monopoly卡塔 尔(英语:State of Qatar)从第一回页面访问开首

在第壹次加载页面时,全部能源都是从网络载的,Service
worker

在第壹遍加载时不会赢得调整互联网响应,它只会在持续访谈页面时起效果。

澳门十大娱乐网址大全 8

页面第二次加载时做到install,并跻身idle状态。

澳门十大娱乐网址大全 9

页面第三次加载时,步入activated状态,计划管理全体的风浪,同时
浏览器会向服务器发送二个异步 诉求来检查Service
worker
自己是还是不是有新的本子,构成了Service
worker
的翻新机制。

澳门十大娱乐网址大全 10

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得到一个promise并接纳它来获取安装成本的光阴以致是不是安装成功。

假如持有的公文都被缓存成功了,那么service
worker就安装成功了。若是别的八个文件下载战败,那么安装步骤就能够退步。那些艺术允许你凭仗于您本身指定的具有能源,不过那意味着你供给特别稳重地调节哪些文件需求在设置步骤中被缓存。钦赐了太多的公文的话,就能够大增设置失利率。

上面只是叁个简短的事例,你能够在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所处的情形是互为隔离的。

澳门十大娱乐网址大全 11

  • 并未浏览页面时也足以运作

收纳系统事件,后台运营

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

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

  • 可升级

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

什么缓存和重返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,这代表必要作者是同源的,非同源(即跨域卡塔 尔(英语:State of Qatar)的伸手也不能够被缓存。
  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

–本文的东家。

处理边界和填坑

那焕发青新禧内容相比新,有点不清待定细节。希望那黄金年代节不慢就不需求讲了(因为标准会管理这几个主题材料——译者注卡塔 尔(阿拉伯语:قطر‎,可是现在,这一个内容依然应当被提一下。

相关文章