Service Worker百科

随着前端快速发展,应用的性能已经变得至关重要,关于这一点大佬做了很多统计。你可以去看看

如何降低一个页面的网络请求成本从而缩短页面加载资源的时间并降低用户可感知的延时是非常重要的一部分。对于提升应用的加载速度常用的手段有Http Cache、异步加载、304缓存、文件压缩、CDN、CSS Sprite、开启GZIP等等。这些手段无非是在做一件事情,就是让资源更快速的下载到浏览器端。但是除了这些方法,其实还有更加强大的Service Worker线程。

Service Worker百科插图

Service Worker与PWA的现状

说起service worker就不得不提起PWA了,service worker做为PWA的核心技术之一,多年来一直被Google大力推广,这里简单介绍一下。

通俗来说,PWA就是渐进式web应用(Progressive Web App)。早在16年初,Google便提出PWA,希望提供更强大的web体验,引导开发者回归开放互联网。它弥补了web对比Native App急缺的几个能力,比如离线使用、后台加载、添加到主屏和消息推送等,同时它还具备了小程序标榜的“无需安装、用完即走”的特性。

虽然PWA技术已经被W3C列为标准,但是其落地情况一直以来是很让人失望的,始终受到苹果的阻碍,最重要的原因在于PWA绕过Apple Store审核,直接推给用户。如果普及,这将威胁到苹果的平台权威,也就意味着苹果与开发者的三七分成生意将会落空。

所以一直以来safrai不支持mainfest以及service worker这两项关键技术,即使在18年开始支持了,但是对PWA的支持力度也远远低于安卓,具体体现在service worker缓存无法永久保存,以及service worker的API支持不够完善,一个最明显的不同在于安卓版本的PWA会保留你的登录状态,并且会系统级推送消息。而在苹果上,这两点都做不到。也就是说,iPhone上的微博PWA,每次打开都要重新登录,而且不会收到任何推送信息。

另外由于某些不可描述的原因,在国内无法使用Service Worker的推送功能,虽然国内已经有两家公司做了service worker的浏览器推送,但是成熟度还有待调研。

由于目前各版本手机浏览器对service worker的支持度都不太相同,同一个接口也存在差异化还有待统一,之于我们来说,也只能用Service Worker做一做PC浏览器的缓存了。

Service Worker的由来

Service Worker(以下简称sw)是基于WEB Worker而来的。

众所周知,javaScript 是单线程的,随着web业务的复杂化,开发者逐渐在js中做了许多耗费资源的运算过程,这使得单线程的弊端更加凹显。web worker正是基于此被创造出来,它是脱离在主线程之外的,我们可以将复杂耗费时间的事情交给web worker来做。但是web worker作为一个独立的线程,他的功能应当不仅于此。sw便是在web worker的基础上增加了离线缓存的能力。当然在 Service Worker 之前也有在 HTML5 上做离线缓存的 API 叫 AppCache, 但是 AppCache 存在很多缺点,你可以亲自看看

sw是由事件驱动的,具有生命周期,可以拦截处理页面的所有网络请求(fetch),可以访问cache和indexDB,支持推送,并且可以让开发者自己控制管理缓存的内容以及版本,为离线弱网环境下的 web 的运行提供了可能,让 web 在体验上更加贴近 native。换句话说他可以把你应用里的所有静态动态资源根据不同策略缓存起来,在你下次打开时不再需要去服务器请求,这样一来就减少了网络耗时,使得web应用可以秒开,并且在离线环境下也变得可用。做到这一切你只需要增加一个sw文件,不会对原有的代码产生任何侵入,是不是很perfect?

Service Worker基本特征

无法操作DOM

只能使用HTTPS以及localhost

可以拦截全站请求从而控制你的应用

与主线程独立不会被阻塞(不要再应用加载时注册sw)

完全异步,无法使用XHR和localStorage

一旦被 install,就永远存在,除非被 uninstall或者dev模式手动删除

独立上下文

响应推送

后台同步

。。。

service worker是事件驱动的worker,生命周期与页面无关。 关联页面未关闭时,它也可以退出,没有关联页面时,它也可以启动。

Dedicated Worker以及Shared Worker与Service Worker三者非常重要的区别在于不同的生命周期。对于Service Worker来说文档无关的生命周期,是它能提供可靠Web服务的一个重要基础。

Service Worker生命周期

Service Worker百科插图1

register 这个是由 client 端发起,注册一个 serviceWorker,这需要一个专门处理sw逻辑的文件

Parsed 注册完成,解析成功,尚未安装

installing 注册中,此时 sw 中会触发 install 事件, 需知 sw 中都是事件触发的方式进行的逻辑调用,如果事件里有 event.waitUntil() 则会等待传入的 Promise 完成才会成功

installed(waiting) 注册完成,但是页面被旧的 Service Worker 脚本控制, 所以当前的脚本尚未激活处于等待中,可以通过 self.skipWaiting() 跳过等待。

activating 安装后要等待激活,也就是 activated 事件,只要 register 成功后就会触发 install ,但不会立即触发 activated,如果事件里有 event.waitUntil() 则会等待这个 Promise 完成才会成功,这时可以调用 Clients.claim() 接管所有页面。

activated 在 activated 之后就可以开始对 client 的请求进行拦截处理,sw 发起请求用的是 fetch api,XHR无法使用

fetch 激活以后开始对网页中发起的请求进行拦截处理

terminate 这一步是浏览器自身的判断处理,当 sw 长时间不用之后,处于闲置状态,浏览器会把该 sw 暂停,直到再次使用

update 浏览器会自动检测 sw 文件的更新,当有更新时会下载并 install,但页面中还是老的 sw 在控制,只有当用户新开窗口后新的 sw 才能激活控制页面

redundant 安装失败, 或者激活失败, 或者被新的 Service Worker 替代掉

Service Worker 脚本最常用的功能是截获请求和缓存资源文件, 这些行为可以绑定在下面这些事件上:

install 事件中, 抓取资源进行缓存

activate 事件中, 遍历缓存, 清除过期的资源

fetch 事件中, 拦截请求, 查询缓存或者网络, 返回请求的资源

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
个人中心
购物车
优惠劵
搜索