创建一个非常简单的离线页面,worker实现加速

时间:2019-10-09 05:20来源:网页制作
使用 Service worker 创立三个特别轻松的离线页面 2016/06/07 · JavaScript· 1 评论 · ServiceWorker 本文由 伯乐在线 -刘健超-J.c翻译,艾凌风校稿。未经许可,禁止转发! 德文出处:DeanHume。应接

使用 Service worker 创立三个特别轻松的离线页面

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

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

让我们想像以下景况:大家那儿在一辆通往农村的列车的里面,用运动设备望着一篇很棒的篇章。与此同时,当您点击“查看越多”的链接时,轻轨卒然进入了隧道,导致移动设备失去了网络,而 web 页面会展现出类似以下的剧情:

澳门金莎娱乐网站 1

那是一定令人寒心的心得!幸运的是,web 开拓者们能通过有个别新特点来改革那类的顾客体验。作者近年径直在折腾 ServiceWorkers,它给 web 带来的数不胜数只怕性总能给自家欣喜。Service Workers 的卓越特质之一是允许你检验互联网要求的处境,并让您作出相应的响应。

在那篇文章里,小编图谋用此天性检查客户的当前网络连接处境,假设没连接则赶回贰个至上轻便的离线页面。固然那是多个不胜基础的案例,但它能给您带来启迪,令你通晓运行并运转该特性是多么的粗略!若是您没通晓过 瑟维斯 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这个周围的服务器和互联网加快之外,通过顾客端达成了更加好的访谈体验。

让大家最初吧

借使你有以下 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('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 时,向缓存加多了离线页面。假若我们将代码分为几小块,可观望前几行代码中,笔者为离线页面内定了缓存版本和U奥德赛L。假若你的缓存有两样版本,那么您只需立异版本号即可简单地排除缓存。在差相当少在第 12 行代码,作者向那些离线页面及其财富(如:图片)发出供给。在得到成功的响应后,我们将离线页面和有关财富充裕到缓存。

明天,离线页面已存进缓存了,大家可在须求的时等候检查索它。在同一个 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 采访网络)

澳门金莎娱乐网站 2

假如你刷新页面,你应当能看见相应的离线页面!

澳门金莎娱乐网站 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都援用了怎么样第三方能源,每种加到忽略列表里。

澳门金莎娱乐网站 4

在根目录下增加offline.html,在未曾网络且缓存中也尚无时利用,效果如下:

澳门金莎娱乐网站 5

在根目录下加多offline.svg,在无网络时图片能源伏乞重回该文件。

开展阅读

其余,还应该有几个很棒的离线效率案例。如:Guardian 创设了三个存有 crossword puzzle(填字游戏)的离线 web 页面 – 因而,纵然等待网络重连时(即已在离线状态下),也能找到一点野趣。小编也援引看看 Google Chrome Github repo,它蕴涵了多数两样的 Service Worker 案例 – 在那之中部分用到案例也在那!

唯独,假若您想跳过上述代码,只是想大致地经过四个库来拍卖相关操作,那么我引入您看看 UpUp。那是一个轻量的剧本,能令你更自在地应用离线功用。

打赏支持作者翻译更加多好小说,多谢!

打赏译者

增长速度效果

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

澳门金莎娱乐网站 6

基于webpagetest

查看测量试验结果

打赏援救小编翻译越多好小说,谢谢!

任选一种支付办法

澳门金莎娱乐网站 7 澳门金莎娱乐网站 8

1 赞 3 收藏 1 评论

加速/离线原理查究

关于我:刘健超-J.c

澳门金莎娱乐网站 9

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

澳门金莎娱乐网站 10

什么是 Service worker

澳门金莎娱乐网站 11

如上图,Service worker 是一种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当多个页面注册了三个 Service worker,它就能够注册一层层事件管理器来响应如互联网恳求和音信推送这个事件。Service worker 能够被用来保管缓存,当响应一个网络必要时得以配备为回去缓存依旧从互连网获取。由于Service worker 是基于事件的,所以它只在拍卖那几个事件的时候被调入内部存款和储蓄器,不用顾忌常驻内部存储器占用财富导致系统变慢。

Service worker生命周期

澳门金莎娱乐网站 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 在第贰次加载时不会获得调控网络响应,它只会在此伏彼起访谈页面时起功效。

澳门金莎娱乐网站 13

页面第二遍加载时产生install,并跻身idle状态。

澳门金莎娱乐网站 14

页面第贰回加载时,步入activated状态,盘算管理全数的平地风波,同时 浏览器会向服务器发送四个异步 央浼来检查Service worker澳门金莎娱乐网站,自个儿是或不是有新的本子,构成了Service worker的翻新机制。

澳门金莎娱乐网站 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所处的情形是相互隔开分离的。

澳门金莎娱乐网站 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能够操纵网址有着的页面,,同理,假如把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

澳门金莎娱乐网站 17

在此间还也有多个要命管用的复选框:

  • Offline

模仿断网状态

  • Update on reload
    加载时更新
  • Bypass for network
    三番五次选择互联网内容
  1. Firefox

除非在Settings里有一个能够在HTTP意况中应用Service worker的选项,适应于调节和测量试验,没有单独网址下的Service worker管理。

澳门金莎娱乐网站 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/

能够见到曾经有二十二个Serviceworker了,在那边能够手动Start让它工作,也能够Unregister卸载掉。

澳门金莎娱乐网站 19

  1. Firefox

有三种情势步入Service worker管制分界面来手动Start或unregister。

  • 菜单栏,Tool->Web Developer->Service workers
  • 位置栏中输入

JavaScript

about:debugging#workers

1
about:debugging#workers

澳门金莎娱乐网站 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 收藏 评论

澳门金莎娱乐网站 21

编辑:网页制作 本文来源:创建一个非常简单的离线页面,worker实现加速

关键词: