有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

service worker(技术干货)详解

服务端 炮渣日记 2周前 (11-15) 27次浏览 已收录 0个评论 扫描二维码
service worker(技术干货)详解

浏览器Service worker初步体验

Service worker是谷歌推出的一项技术,它类似于web worker在其基础上增加了离线缓存的功能,也就是可以在浏览器中进行, 旨在创建更有效的用户体验,拦截网络请求,操作cache。

Service worker无法操作页面dom,运行在其他线程中,不会阻塞其他js运行,不能使用同步API。

使用注册Service worker

Service worker 需要注册以后才能使用,值得注意是以下操作并不推荐,会占用当前网页的资源。

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('sw.js')
}

应该使用 window.addEventListener(‘load’, xxxx) 去操作它保证当前页面的资源加载完成才使用sw.js。

if ("serviceWorker" in navigator) {
    window.addEventListener("load", () => {
        navigator.serviceWorker.register("/sw.js", {}).then(registration => {
            console.log("register succces...")
        }, err => {
            console.log("register error...", err)
        })
    })
}

编写sw.js文件

install属于sw的生命周期,在这里通常可以写一些预缓存的固定资源。

self.addEventListener('install', function (event) {
    event.waitUntil(
        caches.open('my-cache').then(function (cache) {
            return cache.addAll([
                '/css/app.dnakd.css',
                '/js/app.kklds9.js',
            ])
        })
    )
})

Event.waitUntil,是一个方法,它接受一个promise为参数,如果promise成功则不会发生什么,但是失败的话,整个状态install就会失败。还有一个作用就是延长当前事件的生命周期,不会让状态被确定。总之就是可以保证线程中的事件都能正常完成。

caches.open 返回一个promise resolve为Cache对象, 如果指定缓存不存在就创建它,并返回。

cache.addall 接受一个url字符串数组,请求他们并将响应存在缓存中。catch也有单独的cache.add方法。

add() 方法在功能上等同于以下代码:

fetch(url).then(function (response) {
  if (!response.ok) {
    throw new TypeError('bad response status');
  }
  return cache.put(url, response);
})

activate是安装成功后的生命周期

每次更新sw应当删除老旧的缓存,这里是删除全部缓存。

self.addEventListener("activate", function (event) {
    event.waitUntil(
        caches.keys().then(function (keyList) {
            return Promise.all(keyList.map(function (key) {
                return caches.delete(key);
            }));
        })
    );
});

以下是Stale-while-revalidate 策略, 如果有缓存用缓存,异步自动更新。(来自谷歌文档)

self.addEventListener('fetch', function (event) {
    event.respondWith(
        caches.open('mysite-dynamic').then(function (cache) {
            return cache.match(event.request).then(function (response) {
                var fetchPromise = fetch(event.request).then(function (networkResponse) {
                    cache.put(event.request, networkResponse.clone());
                    return networkResponse;
                })
                return response || fetchPromise;
            })
        })
    );
});

event.respondWith 参数为一个reslove为response对象的promise, 防止浏览器的默认fetch处理,并允许你自己提供一个promise响应。

当然实际操作肯定要对请求进行匹配,到底要缓存哪些资源。

喜欢 (0)
炮渣日记
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址