离线访问静态blog网址,创立一个特别轻便的离线页面

永利402com官方网站

行使 Service worker 创设二个特简单的离线页面

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

本文由 伯乐在线 –
刘健超-J.c
翻译,艾凌风
校稿。未经许可,禁绝转发!
德文出处:Dean
Hume。应接参预翻译组。

让大家想像以下境况:我们此时在风流倜傥辆通往村落的列车的里面,用运动器具望着风流倜傥篇很棒的稿子。与此同不经常候,当您点击“查看越来越多”的链接时,高铁忽地步入了隧道,导致移动设备失去了互联网,而
web 页面会展现出相近以下的从头到尾的经过:

永利402com官方网站 1

那是生机勃勃对一令人心寒的心得!幸运的是,web
开垦者们能由此一些新特色来改革这类的客商体验。作者多年来一直在折腾 ServiceWorkers,它给 web 带来的点不清大概性总能给自家欣喜。瑟维斯 Workers
的名牌产品特产产品优品特质之一是允许你检验互联网需要的场景,并让您作出相应的响应。

在此篇作品里,作者准备用此性子检查顾客的近期网络连接意况,假若没连接则赶回多少个拔尖简单的离线页面。就算那是叁个拾叁分基础的案例,但它能给你带来启示,让你明白运维并运营该特性是何其的粗略!借令你没驾驭过
Service Worker,笔者提议您看看此 Github
repo,了然愈来愈多相关的消息。

在这里案例发轫前,让大家先轻松地探访它的办事流程:

  1. 永利402com官方网站,在客户第一次访问大家的页面时,我们会安装 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那些何足为奇的服务器和网络加速之外,通过客商端达成了更加好的寻访体验。

让我们起头吧

举个例子你有以下 HTML 页面。那就算可怜基础,但能给您完整思路。

XHTML

<!DOCTYPE html>

1
<!DOCTYPE html>

跟着,让大家在页面里登记 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(‘瑟维斯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‘。大家企图用那么些 瑟维斯 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
时,向缓存加多了离线页面。假设大家将代码分为几小块,可看出前几行代码中,我为离线页面钦点了缓存版本和U路虎极光L。假使您的缓存有例外版本,那么你只需立异版本号就能够简单地消释缓存。在大意在第
12
行代码,小编向这一个离线页面及其能源(如:图片)发出央浼。在赢得成功的响应后,大家将离线页面和连锁财富丰裕到缓存。

现行反革命,离线页面已存进缓存了,大家可在急需的时等候检查索它。在同叁个 ServiceWorker 中,大家要求对无网络时再次回到的离线页面增加相应的逻辑代码。

JavaScript

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); })
); } });

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 访谈互联网)

永利402com官方网站 2

只要你刷新页面,你应有能看见相应的离线页面!

永利402com官方网站 3

假使您只想差不离地质度量试该意义而不想写任何代码,那么你能够访问笔者已开立好的
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都援引了何等级三方能源,每一个加到忽视列表里。

永利402com官方网站 4

在根目录下增加offline.html,在未有互联网且缓存中也绝非时使用,效果如下:

永利402com官方网站 5

在根目录下增多offline.svg,在无互联网时图片财富央浼重回该文件。

开展阅读

除此以外,还应该有多少个很棒的离线功能案例。如:Guardian 塑造了贰个颇有 crossword
puzzle(填字游戏)的离线
web 页面 –
由此,纵然等待互连网重连时(即已在离线状态下),也能找到一点乐趣。作者也推荐看看
Google Chrome Github
repo,它包蕴了众多不等的
Service Worker 案例 – 个中部分施用案例也在此!

然则,假使您想跳过上述代码,只是想大概地通过多少个库来拍卖相关操作,那么作者引进您看看
UpUp。那是三个轻量的台本,能让您更自在地应用离线作用。

打赏援救自个儿翻译越多好小说,感激!

打赏译者

加速效果

首页加速后,网络要求从16降为1,加载时间从2.296s降为0.654s,获得了风度翩翩晃加载的结果。

永利402com官方网站 6

基于webpagetest

查看测量试验结果

打赏帮衬小编翻译越来越多好作品,多谢!

任选意气风发种支付办法

永利402com官方网站 7
永利402com官方网站 8

1 赞 3 收藏 1
评论

加紧/离线原理探寻

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

永利402com官方网站 9

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

永利402com官方网站 10

什么是 Service worker

永利402com官方网站 11

如上图,Service
worker

是生龙活虎种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当三个页面注册了二个
Service
worker
,它就足以登记生龙活虎多元事件管理器来响应如互连网央浼和新闻推送那些事件。Service
worker

能够被用来治本缓存,当响应三个网络乞请时可以陈设为回到缓存依然从网络得到。由于Service
worker

是依赖事件的,所以它只在拍卖这一个事件的时候被调入内部存款和储蓄器,不用忧郁常驻内部存款和储蓄器占用财富导致系统变慢。

Service worker生命周期

永利402com官方网站 12

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

在首次加载时不会拿走调整互联网响应,它只会在后续访谈页面时起效果。

永利402com官方网站 13

页面第一次加载时产生install,并步入idle状态。

永利402com官方网站 14

页面第一回加载时,步入activated状态,筹算管理全体的平地风波,同时
浏览器会向服务器发送贰个异步 须要来检查Service
worker
作者是还是不是有新的版本,构成了Service
worker
的更新机制。

永利402com官方网站 15

Service
worker
管理完全部的平地风波后,步入idle状态,最后步向terminated状态财富被放出,当有新的风云发生时再度被调用。

特点

  • 浏览器

谷歌 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所处的景况是互为隔开分离的。

永利402com官方网站 16

  • 平素不浏览页面时也能够运作

收到系统事件,后台运转

  • 事件驱动,须要时运转,无需时就终止

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

  • 可升级

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

落到实处加速/离线

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
能够垄断(monopoly)网址有着的页面,,同理,如若把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);
    });

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);

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

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

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

管理 Service worker

一定网址

  1. Google Chrome

Developer Tools->Application->Service Workers

永利402com官方网站 17

在这里处还应该有五个可怜管用的复选框:

  • Offline

效仿断网状态

  • Update on reload
    加载时更新
  • Bypass for network
    连续几天选择网络内容
  1. Firefox

独有在Settings里有二个能够在HTTP碰到中运用Service
worker
的选项,适应于调节和测量检验,未有单独网址下的Service
worker
管理。

永利402com官方网站 18

  1. Opera及其余双核浏览器同Google Chrome
    举个例子看见多少个同样范围内的多个Service
    worker
    ,说明Service
    woker
    更新后,而原有Service
    worker
    还平昔不被terminated。

浏览器全局

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

  1. Google Chrome

在地址栏里输入:

JavaScript

chrome://serviceworker-internals/

1
chrome://serviceworker-internals/

能够见见曾经有贰10个Serviceworker了,在这里处能够手动Start让它专门的学问,也能够Unregister卸载掉。

永利402com官方网站 19

  1. Firefox

有二种办法步入Service
worker
治本分界面来手动Start或unregister。

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

JavaScript

about:debugging#workers

1
about:debugging#workers

永利402com官方网站 20

  1. Opera及任何双核浏览器同Google Chrome

更多

TODO:

  • Service
    workers
    的立异须求手动编辑version,每趟公布新文章时索要编写制定。
  • 使用AMP让页面渲染速度达到最高。

Ref links

Service Worker Cookbook

Is service worker
ready?

Chrome service worker status
page

Firefox service worker status
page

MS Edge service worker status
page

WebKit service worker status
page

1 赞 2 收藏
评论

永利402com官方网站 10

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图