MoeCEO

MoeCEO

Typecho 启用 Service Workers 浏览器缓存加速

2
0
0
2024-06-15

起因

本博客在使用Typecho的时期就缓存加速方面使用过许多方案,但总体都不甚理想。一天在火车上无聊的我在看博友文章的时候发现了喵斯基的一篇文章。[Typecho 启用 Service Workers 浏览器缓存加速首屏访问]

我扫了一眼就把它丢到了我的手机浏览器收藏夹吃灰了。过了三个多月,我在整理收藏夹的时候发现了这篇文章。于是搬出来实践一下。发现效果非常nice。

教程

HTTPS启用

要想使用Service Workers方案必须要网站是使用HTTPS进行访问。这里我使用的是Let‘s Encrypt免费SSL(腾讯云有免费的一年期ssl)。

sw-toolbox.js

下载保存 [sw-toolbox.js]文件到主题目录下(静态文件存放的目录),大多是存放在 assets 目录之下。

serviceworker.js

创建缓存规则,在网站根目录新建一个名为serviceworker.js的文件。文件内容如下(根据自己情况进行修改!!!):

'use strict';

(function () {
    'use strict';
    /**
    * Service Worker Toolbox caching
    */

    var cacheVersion = '-toolbox-v1';
    var dynamicVendorCacheName = 'dynamic-vendor' + cacheVersion;
    var staticVendorCacheName = 'static-vendor' + cacheVersion;
    var staticAssetsCacheName = 'static-assets' + cacheVersion;
    var contentCacheName = 'content' + cacheVersion;
    var maxEntries = 200;

    self.importScripts('usr/themes/主题文件夹名称/assets/sw-toolbox.js');

    self.toolbox.options.debug = false;

    // 缓存本站静态文件
    self.toolbox.router.get('/usr/(.*)', self.toolbox.cacheFirst, {
        cache: {
            name: staticAssetsCacheName,
            maxEntries: maxEntries
        }
    });

    // 缓存 Gravatar 头像
    self.toolbox.router.get('/avatar/(.*)', self.toolbox.cacheFirst, {
        origin: /(secure\.gravatar\.com)/,
        cache: {
            name: staticVendorCacheName,
            maxEntries: maxEntries
        }
    });

    // 缓存 Google 字体
    self.toolbox.router.get('/(.*)', self.toolbox.cacheFirst, {
        origin: /(fonts\.googleapis\.com)/,
        cache: {
            name: staticVendorCacheName,
            maxEntries: maxEntries
        }
    });
    self.toolbox.router.get('/(.*)', self.toolbox.cacheFirst, {
        origin: /(fonts\.gstatic\.com)/,
        cache: {
            name: staticVendorCacheName,
            maxEntries: maxEntries
        }
    });

    // immediately activate this serviceworker
    self.addEventListener('install', function (event) {
        return event.waitUntil(self.skipWaiting());
    });

    self.addEventListener('activate', function (event) {
        return event.waitUntil(self.clients.claim());
    });

})();

注:

  1. Ser­vice Worker 不适用于缓存头为 Cache-control: no-store 或者 no-cache 的文件;

  2. typecho 涉及到的主题及插件都集中存放在 usr 目录,因此上面的缓存规则针对 usr 目录下的所有文件。

引入serviceworker.js

在主题的footer.php文件闭合标签 之前加入下面的代码:

<script>
    var serviceWorkerUri = '/serviceworker.js';
    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register(serviceWorkerUri).then(function() {
            if (navigator.serviceWorker.controller) {
                console.log('Service woker is registered and is controlling.');
            } else {
                console.log('Please reload this page to allow the service worker to handle network operations.');
            }
        }).catch(function(error) {
            console.log('ERROR: ' + error);
        });
    } else {
        console.log('Service workers are not supported in the current browser.');
    }
</script>

取消对serviceworker.js文件的缓存

为了防止在浏览器需要请求新版本的serviceworker.js文件时,而文件自身被缓存的尴尬局面。这里可以给serviceworker.js文件单独指定缓存头 Cache-control: no-store 或 no-cache。

Ng­inx 配置在 server { 区域内追加内容如下:

# serviceworker.js 不设置缓存
location ~* /(.*)/serviceworker\.js {
    add_header Cache-Control no-cache;
    add_header Pragma no-cache;
    add_header Expires 0;
}

重启NGINX,清理浏览器缓存。

效果如下: