来自 前端知识 2019-09-17 03:26 的文章
当前位置: 金沙澳门官网网址 > 前端知识 > 正文

离线访谈静态blog网址

行使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。
  • 瑟维斯worker是贰个可编制程序的互连网代理,允许开辟者调控页面上拍卖的网络诉求。
  • 在不被应用的时候,它会友善终止,而当它再一次被用到的时候,会被另行激活,所以您无法依据于service worker的onfecth和onmessage的管理函数中的全局状态。如若您想要保存一些长久化的音信,你能够在service worker里使用IndexedDB API。
  • 瑟维斯worker大批量使用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。

瑟维斯 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,那样你能够关闭和再一次展开它,而不会潜移默化到您的新窗口。任何创设在模仿窗口中的注册服务和缓存在窗口被关门时都将熄灭。

瑟维斯 worker的调整从第一遍页面访问开首

在第壹次加载页面时,全数财富都以从互联网载的,Service worker 在第三回加载时不会获得调控网络响应,它只会在继续访问页面时起功用。

图片 8

页面第三遍加载时做到install,并步向idle状态。

图片 9

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

图片 10

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

特点

  • 浏览器

谷歌 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,那代表诉求作者是同源的,非同源(即跨域)的伸手也不能够被缓存。
  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 –本文的东道主。

拍卖边界和填坑

这一节内容比较新,有十分的多待定细节。希望这一节极快就无需讲了(因为规范会管理这几个标题——译者注),然而以后,那几个剧情依旧应当被提一下。

本文由金沙澳门官网网址发布于前端知识,转载请注明出处:离线访谈静态blog网址

关键词: