Service Workers使网站速度再次提升一个台阶

释放双眼,带上耳机,听听看~!

介绍

Service Workers 是 Google 爸爸推出很久的一个黑科技,它可以在浏览器层面动态缓存一些请求,从而使网站的二次加载速度大幅提高。说白了就是一个命令浏览器缓存的js脚本。

jiasu.png

第二次访问就会快很多,我的博客二次访问只请求了80多k的数据。

需要注意的是,Service Workers 仅支持HTTPS协议的站点。

添加 sw-toolbox 核心

将如下代码保存为sw-toolbox.js至网站根目录

'use strict';

const version = 'v20160443';
const __DEVELOPMENT__ = false;
const __DEBUG__ = false;
const offlineResources = [
  '/',
  '/offline.html',
  '/offline.svg'
];

const ignoreFetch = [
  /https?://cdn.bootcss.com//,
  /https?://static.duoshuo.com//,
  /https?://www.google-analytics.com//,
  /https?://hm.baidu.com//,
  /https?://p1.music.126.net//,

];


//////////
// 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!');
    });
}

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

function networkedOrCached(request) {
  return networkedAndCache(request)
    .catch(() => { return cachedOrOffline(request) });
}

// Stash response in cache as side-effect of network request
function networkedAndCache(request) {
  return fetch(request)
    .then((response) => {
      var copy = response.clone();
      caches.open(cacheKey('resources'))
        .then((cache) => {
          cache.put(request, copy);
        });

      log("(network: cache write)", request.method, request.url);
      return response;
    });
}

function cachedOrNetworked(request) {
  return caches.match(request)
    .then((response) => {
      log(response ? '(cached)' : '(network: cache miss)', request.method, request.url);
      return response ||
        networkedAndCache(request)
          .catch(() => { return offlineResponse(request) });
    });
}

function networkedOrOffline(request) {
  return fetch(request)
    .then((response) => {
      log('(network)', request.method, request.url);
      return response;
    })
    .catch(() => {
      return offlineResponse(request);
    });
}

function cachedOrOffline(request) {
  return caches
    .match(request)
    .then((response) => {
      return response || offlineResponse(request);
    });
}

function offlineResponse(request) {
  log('(offline)', request.method, request.url);
  if (request.url.match(/.(jpg|png|gif|svg|jpeg)(?.*)?$/)) {
    return caches.match('/offline.svg');
  } else {
    return caches.match('/offline.html');
  }
}

///////////
// 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.');
    });
}

function cacheKey() {
  return [version, ...arguments].join(':');
}

function log() {
  if (developmentMode()) {
    console.log("SW:", ...arguments);
  }
}

function shouldAlwaysFetch(request) {
  return __DEVELOPMENT__ ||
    request.method !== 'GET' ||
      ignoreFetch.some(regex => request.url.match(regex));
}

function shouldFetchAndCache(request) {
  return ~request.headers.get('Accept').indexOf('text/html');
}

function developmentMode() {
  return __DEVELOPMENT__ || __DEBUG__;
}

log("Hello from ServiceWorker land!", version);

self.addEventListener('install', onInstall);

self.addEventListener('fetch', onFetch);

self.addEventListener("activate", onActivate);

修改不用缓存的地址

在sw-toolbox.js文件中找到如下代码

 const ignoreFetch = [
      /https?://cdn.bootcss.com//,
      /https?://static.duoshuo.com//,
      /https?://www.google-analytics.com//,
      /https?://hm.baidu.com//,
      /https?://p1.music.126.net//,
    
    ];

启用 Service Workers

在主题下的主题的全局文件 </body> 标签前加入下面代码

<script>
if ('serviceWorker' in navigator) {
 navigator.serviceWorker.register('/sw-toolbox.js');
}
</script>

离线模式

已知该模式和本站用的yudo主题的pjax冲突。

在网站根目录下创建offline.html可以在没有网络且缓存中也没有时使用,任何没有缓存的页面都会载入这个页面。

在网站根目录下创建offline.svg,在无网络时图片资源请求返回该文件。

参考:http://wangkaibo.com/node-express-ghost-progressive-web-apps-pwa/

 [https://yangbo.tech/2017/01/15/2017-01-15-speedy-and-offline-site-by-service-worker/][3

给TA买糖
共{{data.count}}人
人已赞赏
电影

如何在PC上正确播放4K HDR视频

2020-4-29 15:23:26

其他

【失效】M1905电影网付费电影部分采集(截至2018.10.21) All.M1905.VIP.Movies.Top.Resolution.By.2017.H264.AAC-JBY 1TB

2018-11-22 15:23:56

搜索