作者:Felix Gerschau
译者:前端小智
起源:Felix Gerschau
最近开源了一个 Vue 组件,还不够欠缺,欢送大家来一起欠缺它,也心愿大家能给个 star 反对一下,谢谢各位了。
github 地址:https://github.com/qq44924588…
service worker 是什么
Service Worker 是 Chrome 团队提出和力推的一个 WEB API,用于给 web 利用提供高级的可继续的后盾解决能力。该 WEB API 规范起草于 2013 年,于 2014 年纳入 W3C WEB 规范草案,以后还在草案阶段。
Service Worker 最次要的特点是:在页面中注册并装置胜利后,运行于浏览器后盾,不受页面刷新的影响,能够监听和截拦作用域范畴内所有页面的 HTTP 申请。
相似一个服务器与浏览器之间的中间人角色,如果网站中注册了service worker
那么它能够拦挡以后网站所有的申请,进行判断(须要编写相应的判断程序),如果须要向服务器发动申请的就转给服务器,如果能够间接应用缓存的就间接返回缓存不再转给服务器。从而大大提高浏览体验。
Service Worker
能够启用以前原生应用程序专有的一组性能。Service Worker 的初稿已于 2014 年公布,当初所有支流浏览器都反对它们。
就像曾经指出的定义一样,Service Worker 是网络代理。这意味着它们能够管制页面中的所有网络申请,并且能够对其进行编程,应用缓存的进行响应。
Service Worker 特点
- 网站必须应用
HTTPS
。除了应用本地开发环境调试时(如域名应用localhost
) - 运行于浏览器后盾,能够管制关上的作用域范畴下所有的页面申请
- 独自的作用域范畴,独自的运行环境和执行线程
- 不能操作页面 DOM。但能够通过事件机制来解决
如何注册 Service Worker
注册 Service Worker 不须要太多代码,只须要一个用于Service Worker
代码的 JS 文件,个别取名为 service-worker.js
// 首先查看浏览器是否反对 Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/sw/service-worker.js')
.then(function(registration) {console.log(registration);
})
.catch(function(err) {console.log(err);
});
}
其实要害代码只有一行:
navigator.serviceWorker.register('/sw/service-worker.js')
留神:
Service Worker 的注册门路决定了其 scope
默认作用范畴。示例中 service-worker.js
是在 /sw
门路下,这使得该 Service Worker 默认只会收到 /sw
门路下的 fetch
事件。如果寄存在网站的根门路下,则将会收到该网站的所有 fetcg
事件。
如果心愿扭转它的作用域,可在第二个参数设置 scope
范畴。示例中将其改为了根目录,即对整个站点失效。
另外应意识到这一点:Service Worker 没有页面作用域的概念,作用域范畴内的所有页面申请都会被以后激活的 Service Worker 所监控。
Service Worker 能够启用哪些性能?
在本节中,我将进一步具体介绍 Service Worker 的性能,包含一些小代码示例。
服务工作者启用以下性能,这些性能也是 PWA
的外围:
- 离线性能
- 定期后盾同步
- 推送告诉
离线性能
Service Worke 通过缓存资源和拦挡网络申请来提供离线性能,这些申请能够与先前缓存的资源一起应用,而不是从新申请服务器。
咱们能够从中得出两个步骤:
- 预缓存
- 从缓存中解决申请
这两个步骤都利用了 Cache API,它由 Web Workers 和浏览器应用,并且为咱们提供了用于网络申请的存储机制。
对 Web 和服务工作人员上下文的 localStorage
拜访被阻止,以避免并发性问题。作为一种代替计划,IndexedDB
能够用于存储大量数据。
预缓存
预缓存 是一个术语,形容了在 Service Worker 处于激活状态之前下载和缓存文件。它是在 Service Worker 生命周期的“install
”步骤中实现的。一旦 Service Worker 处于激活状态,它将筹备为缓存中的文件提供服务。
通常,咱们要缓存 Application Shell
,这是运行网站所需的起码代码量。如果开发了本机应用程序,那么这就是您将上传到应用程序商店的代码包。这包含所有必须的根本 JavaScript,HTML 和图片。
self.addEventListener('install', function(event) {
event.waitUntil(caches.open(currentCache.offline).then(function(cache) {
return cache.addAll([
'/static/images/offline.svg',
'/static/html/offline.html',
]);
});
);
});
从缓存中解决申请
在此阶段,咱们曾经将所有利用程序代码存储在缓存中,并且 Service Worker
已处于 激活
即运行于浏览器后盾。
当初惟一短少的是监听 fetch
事件并从缓存中返回后果。能够通过 fetch
事件能够拦挡到以后作用域范畴内的 http/https 申请,并且给出本人的响应。联合 Fetch API,能够简略不便地解决申请响应,实现对网络申请的管制。
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).then(function(response) {return response || fetch(event.request);
})
);
});
在本例中,咱们尽可能应用缓存的内容进行响应。作为回退,咱们收回一个网络申请。
这里实现了一个 缓存优先
、 降级解决
的策略逻辑:监控所有 http
申请,当申请资源曾经在缓存里了,间接返回缓存里的内容;否则应用 fetch
API 持续申请,如果是 图片或 css
、js
资源,申请胜利后将他们退出缓存中;如果是离线状态或申请出错,则降级返回预缓存的离线内容。
定期后盾同步
正如在引言中曾经提到的那样,Service Worker 与其余服务工作者在一个独自的线程上运行,所以即便敞开页面,它们也能够执行其代码。此性能对于执行后盾同步和提供推送告诉很重要。
后盾同步
用户来到页面后,后盾同步通常用于同步数据。
例如,在手机上编辑文档后,咱们写完会点击“保留”并来到页面。如果在编辑文档期间连贯断开,咱们必须期待连贯复原能力保存文档。
后盾同步的目标是解决这个问题,一旦连贯从新建设,主动发送数据。
来看一个示例:
app.js
navigator.serviceWorker.ready.then((registration) => {return registration.sync.register('sync-save-document');
});
service-worker.js
self.addEventListener('sync', (event) => {if (event.tag === 'sync-save-document') {event.waitUntil(saveDocument());
}
});
saveDocument
是一个返回 Promise
,如果被回绝(例如因为网络问题),同步将主动重试。
要留神的一件事是,同步标记必须是惟一的。例如,如果我要安顿 5 个“message
”类型的后盾同步,则只有最初一个会通过。因而,在这种状况下,每个标签都应具备惟一的标识符。
定期后盾同步
定期后盾同步解决与失常后盾同步不同的问题。该 API 可用于在后盾更新数据,而不用期待用户。
这对很多应用程序都很有用。有了这项技术,用户能够在没有互联网连贯的状况下浏览最新的新闻文章。
为了避免滥用这一性能,同步的频率取决于浏览器为每个网站设置的站点参与度分数。如果你常常关上一个网页利用,这个频率最多能够达到 12 个小时。
要实现此目标一个要求是,该网站已作为挪动设施上的 PWA
装置并增加到主屏幕。
推送告诉
Service Worker另一个相似本机的个性是推送告诉。咱们通常通过手机短信或社交媒体告诉的模式晓得它们,但它们也能够在台式电脑上应用。
除 Safari 之外,所有支流浏览器都反对它们,而 Safari 对桌面应用程序有本人的实现。
要应用推送告诉,须要设置一台服务器,该服务器会将告诉推送给所有客户端。因为 Service Worker 在后盾在另一个线程上运行,因而即便页面以后未关上,用户也能够看到推送告诉。
推送的实现有两步:
不同浏览器须要用不同的推送音讯服务器。以 Chrome 上应用 Google Cloud Messaging<GCM>
作为推送服务为例,第一步是注册 applicationServerKey
(通过 GCM 注册获取),并在页面上进行订阅或发动订阅。每一个会话会有一个独立的端点(endpoint
),订阅对象的属性(PushSubscription.endpoint
) 即为端点值。将端点发送给服务器后,服务器用这一值来发送音讯给会话的激活的 Service Worker(通过 GCM 与浏览器客户端沟通)。
浏览器反对状况
除了 Safari 和 IE/Edge,大部分古代浏览器都曾经失去了反对。
总结
心愿通过本文介绍基本概念和个性,能够让你更好地了解Service Worker。
代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。
原文:https://felixgerschau.com/ser…
交换
文章每周继续更新,能够微信搜寻「大迁世界」第一工夫浏览和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 曾经收录,整顿了很多我的文档,欢送 Star 和欠缺,大家面试能够参照考点温习,另外关注公众号,后盾回复 福利,即可看到福利,你懂的。