Service Worker

当下PWA比较火,而Service Worker是实现PWA的一项关键技术,今天咱们一块儿了解下关于Service Worker的一些基础知识和适用场景。web

什么是Server Worker

咱们先来看一下官方文档中对于Server Worker的核心定义:chrome

Service workers 本质上充当Web应用程序与浏览器之间的代理服务器,也能够在网络可用时做为浏览器和网络间的代理。

这是一条很准确的定义,但对于不了解Service Worker的同窗来讲可能并不形象,下面咱们更形象的理解一下这个概念。咱们以去银行取钱为例子,其过程大概以下图:浏览器

从上面的图中咱们能够看到,银行的钱存在金库中,客户取钱时并非直接去金库里拿,而是须要经过银行的工做人员,再告知银行工做人员须要多少钱,并出示相应凭证后,由银行工做人员从金库中拿出钱给客户,并从帐户中减去相应金额。这么作的缘由很容易理解,由于金库是公用的,全部客户的钱都放在里面,咱们没法保证每一个客户都能只拿走属于本身的钱,并按照实际状况更新金库记录。缓存

咱们的应用在请求服务器资源时,其过程也是相似的:服务器

从上面的图能够看到,请求资源的过程当中,HTTP协议充当了取钱过程当中的银行工做人员,客户端应用须要的资源在服务器上,但应用却没法直接去服务器获取资源,而是经过HTTP协议进行,请求中指定的各类Header信息,就是取钱时的凭证。网络

而Service Worker能够理解成,在客户端建立了一个属于本身的金库,先看图:工具

当咱们须要取钱或者获取资源时,能够先从本地的金库中拿,本地金库没有,再经过原来的流程获取。这时咱们再回头看文章开始的定义,应该就可以理解了。优化

Service Worker与Cache的关系

正常状况下,客户端获取一个资源的过程有以下三步:this

而关于请求资源的优化,通常也集中在这三步完成:spa

  1. 不发出请求就可以得到资源;
  2. 提升服务器查找资源的速度;
  3. 减少返回内容的体积;

看完上面的部分咱们能够发现,当使用Service Worker中已有的资源时,客户端应用获取资源并无进入HTTP请求的流程,也就是说,经过Service Worker,客户端应用能够在不发出请求的状况下得到资源,这很容易就让咱们想到缓存,那么Service Worker和咱们平时常常提到的强缓存和协商缓存等是什么关系呢?整理了一个图,能够先看下:

从总体上来讲,应用获取一个资源的缓存类型分为上图中的四种,分别是Service Worker、Memory Cache、Disk Cache和No Cache。资源查找顺序为从左向右,找到资源则返回,未找到则继续寻找,直至最终获取资源。上面的图中能够清楚的看出Service Worker在缓存类型中的位置,也能看到跟平时常常提到的强缓存和协商缓存的关系。

Service Worker使用逻辑

在了解了Service Worker的概念后,咱们看下Servise Worker的基本使用逻辑,使用它的基础过程是首先注册一个Woker,这时浏览器会在后台启动一个新的线程,在这个线程启动后,会按照Service Worker中的代码逻辑将一些资源缓存下来,缓存完毕后,启动对页面请求的监听,当监听到页面请求资源时能够作出相对应的响应,好比若是资源在Service Worker中缓存过了,就能够直接返回资源。

注册

Service Worker对象保存在window.navigator内,首先调用register方法进行注册,导入一个js文件,文件中是咱们的Service Worker逻辑,代码以下:

navigator.serviceWorker.register('/sw.js')
.then(function(reg){
    console.log("success", reg);
}).catch(function(err) {
    console.log("error", err);
});

须要注意的是Service Worker是有做用域的,它的做用域为文件的当前路径,Service Worker文件只能管理本身做用下的资源,好比abcde.com/home/sw.js 的做用域为abcde.com/home/。

激活

注册后的Service Worker就能在调试工具中看到了,下面是一个chrome调试面板的截图:

画红框的内容是一些比较关键的信息,好比其中代表了Service Worker的文件名和路径,以及当前Service Worker的状态,Service Worker的状态分为几种,STOPPED(已中止)、STARTING(正在启动)、RUNNING(正在运行)和STOPPING(正在中止),好比上面的截图就处于RUNNING状态。

只有处于running状态的Service Worker才能生效,这就须要对注册后的Service Worker进行加载和激活,注册完毕后,Service Worker会自动开始下载,下载后会触发install事件,咱们能够监听这个事件并进行下载资源的操做,代码以下:

const CACHE_NAME = "demo-a";
this.addEventListener("install", function(event) {
    console.log("install service worker success");
    caches.open(CACHE_NAME);
    let cacheResources = ["https://abcde.com/demo.js"];
    event.waitUntil(
        caches.open(CACHE_NAME).then(cache => {
            cache.addAll(cacheResources);
        })
    );
});

通过上面的代码,demo.js文件就被咱们缓存下来了,下载完后Service Worker就会执行激活:

this.addEventListener("active", function(event) {
    console.log("service worker active success");
});

此时咱们经过开发者工具就能看到一个激活的Service Worker了,总体梳理一下大概是下面的过程:

须要注意的是,图中灰色的部分是一个独立的特殊线程,并非浏览器渲染页面执行js的线程,所以使用Service Worker的过程当中无需担忧会影响页面的渲染。

更新

咱们注册了Service Worker后,还面临着更新的问题,当咱们的业务迭代时必然要更新Service Worker,在咱们理解了它的整个注册过程后,理解更新就很简单了,直接上图:

当应用加载时,会下载Service Worker文件,这是在浏览器中就会有两个文件,一个是当前正在使用的Service Worker,一个是新下载的Service Worker,当新下载的文件下载完毕后,浏览器会对两个文件进行Diff操做,若是发现文件没有更新,则会丢弃掉新下载的Service Worker文件,若是发现有变化,则会加载新的Service Worker,但新加载的Service Worker会处于wating状态,并不会实际发挥做用,只有当整个浏览器中对正在运行的Service Worker没有依赖时,才会将运行中的Service Worker抛弃,将新的Servier Worker置为激活状态。

常见使用场景

  1. 用于浏览器缓存,提升加载速度;
  2. 实现离线应用,最近PWA如此火爆;
  3. 实现消息的主动推送,为web应用增长一种给力的交互方式;

兼容性

咱们了解一些Service Worker的基础知识,以及一些比较常见的使用场景,那么目前Service Worker的兼容性如何呢,看下图

目前主流的现代浏览器支持度仍是不错的,可是到目前为止全系列的IE浏览器均不支持Service Worker,并且有一点感觉很明显,在查资料的过程当中,看了网上很多的博客,不一样的博客上也有当时写博客时的Service Worker支持度,能够明显感受到Service Worker的支持程度在快速提高,随着支持度的提高,相信会有愈来愈多的开发者在项目中使用这项技术。

借助Service Worker,真正让PWA应用变得流行,也许就在不久的未来。

相关文章
相关标签/搜索