创建一个非常简单的离线页面,加速网站访问的最佳实践

应用瑟维斯 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 创制一个万分简单的离线页面

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

本文由 伯乐在线 –
刘健超-J.c
翻译,艾凌风
校稿。未经许可,禁止转发!
英文出处:Dean
Hume。欢迎参与翻译组。

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

图片 1

这是一对一令人寒心的经验!幸运的是,web
开发者们能通过有些新特征来创新那类的用户体验。我多年来从来在折腾 ServiceWorkers,它给 web 带来的无尽大概性总能给本身惊喜。Service Workers
的大好特质之一是同意你检测互连网请求的光景,并让你作出相应的响应。

在这篇小说里,我打算用此本性检查用户的当前互连网连接处境,如果没连接则赶回一个超级简单的离线页面。尽管那是一个不行基础的案例,但它能给您带来启迪,让你驾驭启动并运行该天性是何等的简约!即使您没了然过
Service Worker,我提出你看看此 Github
repo,精晓更加多相关的新闻。

在该案例早先前,让大家先不难地看看它的行事流程:

  1. 在用户首次访问我们的页面时,大家会安装 ServiceWorker,并向浏览器的缓存添加大家的离线 HTML 页面
  2. 下一场,如若用户打算导航到另一个 web
    页面(同一个网站下),但此刻已断网,那么大家将再次回到已被缓存的离线
    HTML 页面
  3. 但是,即使用户打算导航到别的一个 web
    页面,而这时网络已接连,则能照常浏览页面

Varnish 的局地特点:

这是一篇关于 <u>如何加快网站访问速度</u> 的译文,原文出自
雅虎开发者网站,原标题为
Best Practices for Speeding Up Your Web
Site。

加紧/离线访问只需三步

  • 首页添加注册代码

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

在根目录下添加offline.html,在从来不互连网且缓存中也从没时使用,效果如下:

图片 3

在根目录下添加offline.svg,在无网络时图片资源请求再次来到该文件。

让我们开端吧

即使你有以下 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
时,向缓存添加了离线页面。如若大家将代码分为几小块,可看出前几行代码中,我为离线页面指定了缓存版本和URL。如若您的缓存有例外版本,那么您只需立异版本号即可简单地解决缓存。在大体在第
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 访问互联网)

图片 4

假诺你刷新页面,你应当能收算命应的离线页面!

图片 5

假如你只想大约地测试该意义而不想写任何代码,那么你可以访问我已创设好的
demo。别的,上述所有代码可以在
Github repo 找到。

本身领会用在此案例中的页面很简短,但你的离线页面则在于你自个儿!借使您想深切该案例的剧情,你可以为离线页面添加缓存破坏(
cache busting),如:
此案例。

(1)、是基于内存缓存,重启后数据将消失;

以下为译文:

加紧效果

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

图片 6

基于webpagetest

查看测试结果

拓展阅读

除此以外,还有多少个很棒的离线功效案例。如:Guardian 打造了一个装有 crossword
puzzle(填字游戏)的离线
web 页面 –
因而,即使等待互连网重连时(即已在离线状态下),也能找到一点乐趣。我也推荐看看
Google Chrome Github
repo,它含有了无数不一致的
瑟维斯 Worker 案例 – 其中有的施用案例也在那!

可是,若是你想跳过上述代码,只是想差不多地由此一个库来处理相关操作,那么自身推荐您看看
UpUp。那是一个轻量的台本,能让你更轻松地动用离线效用。

打赏扶助本身翻译更加多好作品,感谢!

打赏译者

(2)、利用虚拟内存情势,I/O 品质好;


增速/离线原理探索

打赏协理我翻译越来越多好小说,多谢!

任选一种支付格局

图片 7
图片 8

1 赞 3 收藏 1
评论

(3)、帮衬设置 0~60 秒内的标准缓存时间;

加速网站访问的一流实践

出类拔萃的绩效团队已经规定了一些使网页火速的极品做法。该清单包蕴分为7个品种的35个一级做法。


什么是 Service worker

图片 9

如上图,Service
worker

是一种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当一个页面注册了一个
Service
worker
,它就足以登记一种种事件处理器来响应如互联网请求和新闻推送那几个事件。Service
worker
创建一个非常简单的离线页面,加速网站访问的最佳实践。
可以被用来管理缓存,当响应一个网络请求时方可安顿为回到缓存依旧从互联网得到。由于Service
worker

是依照事件的,所以它只在处理那些事件的时候被调入内存,不用操心常驻内存占用资源导致系统变慢。

关于作者:刘健超-J.c

图片 10

前端,在路上…
个人主页 ·
我的小说 ·
19 ·
    

图片 11

(4)、VCL 配置管理比较灵活;

Content

  1. 最小化 HTTP 请求
    最终用户响应时间的80%用于前端。半数以上光阴都是下载页面中的所有组件:图像,样式表,脚本,Flash等。裁减组件数量又裁减了突显页面所需的HTTP请求数量。那是更快页面的重点。

减去页面中组件数量的一种方法是简化页面的规划。不过,有没有点子打造更丰裕内容的页面,同时也能落到实处火速的响应时间?以下是缩减HTTP请求数量的部分技术,同时依然支撑添加的页面设计。

构成文件
是通过将享有脚本组合到单个脚本中以及将富有CSS组合到单个样式表中的主意来裁减HTTP请求的数量。当脚本和样式表从页到页差别时,组合文件更具挑战性,但使那有的版本进程可以改良响应时间。

CSS
Sprites
是减弱图像请求数量的首选办法。将你的背景图像合并为一个图像,并选用CSS
background-imagebackground-position 属性来显示所需的图像段。

图像印象将七个图像组合成单个图像。总体大小差不离相同,但压缩HTTP请求数量会加速页面速度。倘诺图像在页面中是连接的,则图像投射只可以工作,例如导航栏。定义图像投射的坐标或许很麻烦,不难失误。

运用导航图像投射也不得访问,因而不引进使用。
内联图像
使用data:URL方案将图像数据嵌入到实在页面中。那可以增加HTML文档的高低。将内联图像组合到(缓存)样式表中是减掉HTTP请求并防止扩充页面大小的一种艺术。所有主流浏览器都不协助内联图片。

裁减页面中HTTP请求的数量是开头的地点。那是增强首次访问者效率的最根本的指导方针。如Tenni
Theurer的博客小说中所述浏览器缓存使用 –
暴光!,您网站的每一天访问者中有40-60%的空白缓存。

使您的页面很快为这么些率先次访问者是更好的用户体验的主要。

  1. 减少DNS查询
    域名种类(DNS)将主机名映射到IP地址,如同电话簿将人员姓名映射到他们的电话号码一样。当您在浏览器中输入www.yahoo.com时,浏览器联系的DNS解析器会回到该服务器的IP地址。DNS有一个花费。DNS平常须求20-120阿秒来搜寻给定主机名的IP地址。在形成DNS查找以前,浏览器不可以从此主机名下载任何内容。
    缓存DNS查找以得到更好的性质。那种缓存可以在由用户的ISP或局域网维护的差别日常缓存服务器上暴发,不过也设有在个人用户的微处理器上发出的缓存。DNS音信保存在操作系统的DNS缓存(Microsoft
    Windows中的“DNS客户端服务”)中。大部分浏览器都有协调的缓存,与操作系统的缓存分开。只要浏览器将DNS记录封存在融洽的缓存中,就不会对操作系统造成记录请求的分神。
    默许景况下,Internet Explorer会缓存DNS查找30分钟,由
    DnsCacheTimeout注册表设置指定。Firefox缓存DNS查找1分钟,由network.dnsCacheExpiration配置安装控制。(法斯特erfox将其改变为1钟头。)
    当客户端的DNS缓存为空(对于浏览器和操作系统)时,DNS查找的数额相等网页中绝无仅有主机名的数额。那包含在页面的URL,图像,脚本文件,样式表,Flash对象等中应用的主机名。减弱唯一主机名的数据收缩了DNS查找的数据。
    削减唯一主机名的多寡有只怕减弱页面中产生的竞相下载量。幸免DNS查找缩短响应时间,但减去并行下载恐怕会追加响应时间。我的清规戒律是将这一个零件分成至少八个但不超过多少个主机名。那致使裁减DNS查找并同意中度并行下载之间的可观折中。

  2. 防止重定向
    利用301和302情景代码已毕重定向。以下是301响应中HTTP头的演示:

HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html

浏览器自动将用户带到该Location字段中指定的URL。重定向所需的富有音讯都在头文件中。响应的身子一般是空的。即使她们的名字,在实践中也不会缓存301和302的响应,除非额外的标题,例如
Expires或者Cache-Control标志它应该是。元刷新标签和JavaScript是将用户指点到其它URL的别的措施,但要是必须执行重定向,首选技术是运用标准的3xx
HTTP状态代码,重假设为着保障后退按钮正常干活。

要铭记在心的是重定向会放慢用户体验。在用户和HTML文档之间插入重定向会推迟页面中的所有剧情,因为页面中的任何内容都不可以被渲染,并且在HTML文档到达以前不会起来下载任何组件。

最浪费的重定向之一是反复发生的,Web开发人士平常不会发觉到那或多或少。当URL中缺失底部斜线(/)时,会暴发那种情景,否则应当有一个。
例如,去
http://astrology.yahoo.com/astrology
得到一个富含重定向到
http://astrology.yahoo.com/astrology/
(注意添加的底部斜杠)的301响应。即使你使用Apache处理程序,则应用Aliasormod_rewriteor
DirectorySlash命令在Apache中开展修复。

将旧网站接连到新的网站是重定向的另一个科普用途。其余包蕴连日来网站的不等部分,并基于某些原则(浏览器类型,用户帐户类型等)指点用户。使用重定向连接三个网站很粗略,只要求很少的附加编码。即便在那么些情状下接纳重定向会降低开发人士的纷纷,但会下落用户体验。那种使用重定向的替代方案包罗利用Aliasmod_rewrite假诺八个代码路径托管在同等台服务器上。如若域名变化是运用重定向的缘故,一种替代情势是创办一个CNAME与构成(即成立了一个从域名指向另一个别名DNS记录)Aliasmod_rewrite

  1. 使用 Ajax Cacheable
    Ajax的一个引人注意的功利是它为用户提供及时报告,因为它从后端Web服务器异步请求音信。可是,使用Ajax无法保障用户不会等待他们等待异步JavaScript和XML响应重回的拇指。在无数利用中,用户是还是不是保持等待取决于Ajax的利用方法。例如,在依据Web的电子邮件客户端中,用户将不断等待Ajax请求的结果来探寻与其寻找条件万分的有着电子邮件。首要的是要记住,“异步”并不意味着“须臾时”。

为了拉长品质,紧要的是优化这几个Ajax响应。提升Ajax品质的最根本的主意是使响应可缓存,如添加到期或缓存控制头。
一对其它规则也适用于Ajax:

  • Gzip组件
  • 减少DNS查找
  • 缩小JavaScript
  • 幸免重定向
  • 配置ETag

大家来看一个例子。
Web 2.0电子邮件客户端只怕会选取Ajax下载用户的自动完结地址簿。
设若用户上次使用电子邮件网络应用程序后用户没有改动她的地址簿,假设Ajax响应得以应用未来的Expires或Cache-Control标头举办缓存,则可以从缓存读取以前的地址簿响应。必须通报浏览器曾几何时使用此前缓存的地址簿响应,而不是呼吁新的地址簿响应。那足以经过向地址簿Ajax
URL添加一个时日戳来表示,例如,用户最后四次修改她的地址簿&t=1190241612。即使地址簿自上次下载以来没有被修改,则时间戳将是千篇一律的,并且地址簿将从浏览器的缓存中读取,从而扫除额外的HTTP往返。

就是你的Ajax响应是动态创造的,并且只怕仅适用于单个用户,但仍可缓存它们。那样做会使您的Web
2.0应用程序更快。

  1. 后负载组件
    你可以仔细看看您的页面,问问自个儿:“为了最初渲染页面相对必要如何?”
    其他的内容和零部件可以等待。

JavaScript是在onload事件以前和之后拆分的美丽候选者。
诸如,假如你有JavaScript代码和库举行拖放和动画,那么可以等待,因为在开首展现之后拖动页面上的因素。
其余寻找候选人进行中期加载的地方包罗隐藏的情节(用户操作后边世的始末)以及下方的图像。

帮衬您解决难题的工具:YUI Image
Loader允许你将图像延迟到折叠地点,YUI
Get实用程序是一个概括的措施,可以即时包罗JS和CSS。举个例子,在野外看看
Yahoo!主页与Firebug的网络面板打开了。

当品质目的与其他Web开发最佳实践相平等时,那是很好的。
在那种情景下,渐进增强的想法告诉我们,当JavaScript被帮助时,可以革新用户体验,不过你必须确保页面的办事就是没有JavaScript。
因此在确定页面工作例行从此,您可以运用部分后加载脚本来增强它,从而为您提供越多铃声和口哨,如拖放和动画。

  1. 预加载组件
    预加载大概看起来与中期加载相反,但实质上具有差别的靶子。通过预加载组件,您可以动用浏览器空闲的日子,并呼吁将来必要的机件(如图像,样式黄岩乱弹本)。那样当用户访问下一页时,您可以将多数组件放在缓存中,并且您的页面将为用户加载更快。

骨子里有几序列型的预加载:

  • 义诊预 加载 – 一旦加载启动,您就足以继续领取部分出色的组件。
    自我批评google.com,了然怎么请求一个机智图像的加载。
    本条天使图片不需求在google.com主页上,但在连接的搜寻结果页面上是急需的。
  • 有规则的预加载 –
    基于用户操作,您做出有依据的估摸,用户在何地下一步,并相应地预加载。在search.yahoo.com上,你可以看看在输入框中输入后,怎么样请求一些相当的组件。
  • 前瞻预加载 – 在开行重新规划在此以前提前预加载。
    每每重复设计后,您会发觉:“新网站很酷,但比在此以前更慢”。
    难题的一局地或许是用户正在使用完全缓存访问您的旧站点,但新的站点始终是空缓存体验。您可以在启动重新规划此前先行加载某些零部件来减轻这种副作用。您的旧网站可以应用浏览器空闲的时日,并恳请新网站将选拔的图像和本子
  1. 减掉DOM成分的数据
    复杂的页面意味着越来越多的字节下载,也表示JavaScript中的DOM访问速度较慢。如若你想要添加事件处理程序,例如,如果循环访问500或5000个页面上的DOM成分,这将大有可为。

恢宏的DOM元素大概是部分症状,应该采用页面的记号进行改良,而不必删除内容。您是否利用嵌套表展开布局?你是不是<div>只投入越来越多的事物来缓解布局难题?大概有更好的和更语义上正确的办法来做你的记号。

对此布局来说,很大的帮助是YUI
CSS实用程序:grids.css可以辅助你全部布局,fonts.css和reset.css可以协理您剥离浏览器的默许格式。那是一个机遇,开头卓绝和思索你的标记,例如,<div>唯有当它有意义的语义,而不是因为它展现一个新的行。

DOM成分的数量很简单测试,只需输入Firebug的控制台:

 document.getElementsByTagName('*').length

DOM元素有些许?检查其他具备可以标记的类似页面。例如,Yahoo!主页是一个这个繁忙的页面,依然低于700个因素(HTML标签)。

  1. 分开跨域的零件
    细分组件允许你最大程度地互动下载。由于DNS查询损失,请确保您使用的不当先2-4个域。例如,您可以承接你的HTML和动态内容www.example.org里头不相同静电元件static1.example.org和static2.example.org

关于越多信息,请参阅Tenni Theurer和PattyChi的“最大化拼车车道中的并行下载
”。

  1. 最小化iframe的数量
    iframe允许在父文档中插入一个HTML文档。驾驭iframe的办事原理,以便有效的行使尤其重大。
  • <iframe> 优点:
    扶助缓慢的第三方内容,如徽章和广告
    林芝沙箱
    互动下载脚本

  • <iframe> 缺点:
    开支高,尽管空白
    阻止页面加载
    非语义

  1. 没有404s
    HTTP请求是昂贵的,所以暴发HTTP请求并拿走无用的响应(即404 Not
    Found)是完全不须要的,并且会减速用户体验,没有别的利益。

部分网站有协理404s“你的趣味是X?”,那对用户体验格外好,但也会浪费服务器资源(如数据库等)。尤其不佳的是当链接到外部JavaScript是错误的,结果是404.先是,那个下载将截留并行下载。接下来,浏览器大概会尝试解析404响应体,就好像它是JavaScript代码,试图找到可用的事物。


Service worker生命周期

图片 12

Service
worker

为网页添加一个看似于APP的生命周期,它只会响应系统事件,即便浏览器关闭时操作系统也得以提示Service
worker
,那点尤其重要,让web
app与native app的力量变得好像了。

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

一旦Service
worker
居于activated状态,就能够完全控制应用的资源,对互联网请求举行自我批评,修改网络请求,从网络上获取并赶回内容可能再次回到由已设置的Service
worker
预示获取并缓存好的资源,甚至还足以扭转内容并重临给互联网语法。

有着的那些都用户都是晶莹的,事实上,一个企划可以的Service
worker
就如一个智能缓存系统,抓牢了互联网和缓存成效,拔取最优办法来响应互连网请求,让动用越来越安定的周转,固然没有互连网也没涉及,因为您可以完全控制网络响应。

(5)、32位机器上缓存文件大小为最大2G;

Server

Service worker的控制从第二次页面访问开头

在首次加载页面时,所有资源都是从网络载的,Service
worker

在首次加载时不会获得控制网络响应,它只会在继续访问页面时起功效。

图片 13

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

图片 14

页面第二次加载时,进入activated状态,准备处理所有的轩然大波,同时
浏览器会向服务器发送一个异步 请求来检查Service
worker
自我是还是不是有新的版本,构成了Service
worker
的更新机制。

图片 15

Service
worker
拍卖完所有的事件后,进入idle状态,最后进入terminated状态资源被放走,当有新的轩然大波时有发生时再也被调用。

(6)、具有强大的管制功效,例如 top、stat、admin、list 等;

特点

  • 浏览器

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

图片 16

  • 从没浏览页面时也足以运作

收下系统事件,后台运行

  • 事件驱动,必要时运行,不须求时就告一段落

按需实践,只在急需时加载到内存

  • 可升级

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

(7)、状态机设计巧妙,结构清晰;

心想事成加快/离线

(8)、利用二叉堆管理缓存文件,达到积极删除目的。

Cache

网页缓存有众多,如HTTP缓存,localStorage,sessionStorage和cacheStorage都得以灵活搭配举办缓存,但操作太繁琐,直接使用更高级Service
worker

–本文的东道主。

Varnish 的 Storage 方式可分为二种:

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

1)、Malloc 通过 malloc 获取内存;

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

2)、Mmap file 创立大文件,通过二分法分段映射成 1G 以内的大块。

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时将有所符合缓存策略的资源拓展缓存。

以 Mmap file 的缓存方式启动 I/O 也会形成瓶颈,原因根本是 Varnish
缓存的多少先会刷到磁盘上,然后在一遍性读到内存中,那在访问量大的时候还要也会对
I/O 造成很大的下压力。Malloc 缓存格局即便对 I/O
没有压力,因所有缓存数据都写到内存中。

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

Malloc 格局启动:

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

/usr/local/varnish/sbin/varnishd -u nobody -g nogroup -f
/usr/local/varnish/etc/varnish.vcl -s malloc,4G -w 50,51200,120 -a
192.168.10:80 -T 127.0.0.1:8080

管理 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。

Mmap file 格局启动:

浏览器全局

看望您的浏览器里都有怎么着Service worker已经存在了

  1. Google Chrome

在地址栏里输入:

JavaScript

chrome://serviceworker-internals/

1
chrome://serviceworker-internals/

可以见到已经有24个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

/usr/local/varnish/sbin/varnishd -u nobody -g nogroup -f
/usr/local/varnish/etc/varnish.vcl -s
file,/data/varnish/varnish_storage.bin,4G -w 50,51200,120 -a
192.168.10:80 -T 127.0.0.1:8080

更多

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

Varnish 进度的干活格局:

Varnish 启动或有2个经过 master(management) 进度和 child(worker)
进程。master 读入存储配置命令,举行初步化,然后 fork,监控 child。child
则分配线程举办 cache 工作,child 还会做管理线程和变化很多 worker 线程。

 

相关文章