使用Workbox库的Service Worker缓存静态资源加速你的网站

对于静态资源的缓存,浏览器默认依赖HTTP协议头,虽然可以配置,但不细致且不可控。默认情况时,也许你重启浏览器或重启电脑就需要重新下载资源。而Service Worker作为独立运行的脚本,开发者可通过代码主动定义缓存策略,调整缓存行为,控制权完全掌握在开发者手中。并且可以节省服务器或CDN的流量消耗,何乐而不为呢。

使用Workbox接入Service worker

Service Worker是运行在浏览器后台的独立线程,无需页面关联即可运行,主要功能包括资源缓存、离线访问支持、网络请求拦截等。而Workbox是Google开发的开源库,它封装了Service Worker的底层复杂逻辑,提供了预定义的缓存策略、资源更新机制和缓存清理方案,大幅降低了Service Worker的开发门槛。

通过Workbox实现静态资源缓存,可显著减少重复网络请求,提升网站加载速度,尤其在弱网或离线环境下能极大优化用户体验。

Workbox开源仓库地址:https://github.com/GoogleChrome/workbox

网站接入Workbox教程

本文以wordpress为例,进入网站根目录后,上传文末下载的workbox-sw.zip

解压workbox-sw压缩包,得到文件夹和一个js配置文件

图片[1]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

在主题目录的function.php中添加代码

function add_serviceworker_footer() {
    // 资源版本更新(保留版本控制,确保文件更新时触发重新注册)
    $static_ver = "ver=1.0.0";
    ?>
    <script>
        // Service Worker 路径:根目录下的 ws.js,拼接版本号参数
        const serviceWorkerUri = '/serviceworker.js?<?php echo $static_ver; ?>';

        // 检查浏览器是否支持 Service Worker
        if ('serviceWorker' in navigator) {
            // 原生注册 Service Worker
            navigator.serviceWorker.register(serviceWorkerUri)
                .then((registration) => {
                    console.log('Service Worker 注册成功,作用域:', registration.scope);

                    // 监听新 Service Worker 安装完成但未激活的状态
                    registration.addEventListener('waiting', () => {
                        console.log('新的 Service Worker 已安装,关闭所有页面标签后生效');
                    });

                    // 监听 Service Worker 激活事件(首次激活或更新激活)
                    registration.addEventListener('activate', () => {
                        if (navigator.serviceWorker.controller) {
                            console.log('Service Worker 已更新并激活,建议刷新页面');
                        } else {
                            console.log('Service Worker 首次激活成功,开始缓存资源');
                        }
                    });
                })
                .catch((error) => {
                    console.error('Service Worker 注册失败:', error);
                });
        } else {
            console.log('当前浏览器不支持 Service Worker');
        }
    </script>
    <?php
}
add_action('wp_footer', 'add_serviceworker_footer');
图片[2]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

如果你的主题function.php中有类似以下代码,可在主题目录创建指定的php文件用于更新免修改

图片[3]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

这样你就接入完了

serviceworker.js配置

正则匹配实现缓存wordprss上传目录

// 匹配规则:所有路径以/wp-content/uploads/开头的资源(正则表达式匹配)
workbox.routing.registerRoute(
  new RegExp('/wp-content/uploads/(.*)'),
  // 采用CacheFirst(缓存优先)策略:优先从缓存读取,缓存未命中时才请求网络
  // 适合不常变动的静态资源,能减少网络请求,提升加载速度
  new workbox.strategies.CacheFirst({
    cacheName: staticAssetsCacheName, // 缓存名称(通常在外部定义,用于区分不同类型的缓存)
    plugins: [
      // 缓存可响应插件:仅缓存状态码为0(部分无HTTP状态的请求,如Service Worker拦截的请求)或200(成功响应)的资源
      new workbox.cacheableResponse.CacheableResponsePlugin({ statuses: [0, 200] }),
      // 过期插件:限制缓存的最大条目数(maxEntries通常在外部定义),防止缓存无限增长占用过多空间
      new workbox.expiration.ExpirationPlugin({ maxEntries })
    ]
  })
);

缓存三方资源

// 匹配规则:所有来源(origin)为https://at.alicdn.com的资源(通常是第三方库、公共静态资源等)
workbox.routing.registerRoute(
  ({ url }) => url.origin === 'https://at.alicdn.com',
  // 采用CacheFirst(缓存优先)策略:优先从缓存读取,缓存未命中时才请求网络
  // 适合不常变动的静态资源,能减少网络请求,提升加载速度
  new workbox.strategies.CacheFirst({
    cacheName: staticVendorCacheName, // 缓存名称(区分于本地静态资源缓存)
    plugins: [
      // 缓存可响应插件:仅缓存状态码为0(部分无HTTP状态的请求,如Service Worker拦截的请求)或200(成功响应)的资源
      new workbox.cacheableResponse.CacheableResponsePlugin({ statuses: [0, 200] }),
      // 过期插件:限制缓存的最大条目数(maxEntries通常在外部定义),防止缓存无限增长占用过多空间
      new workbox.expiration.ExpirationPlugin({ maxEntries })
    ]
  })
);

官方示例:

// 配置Workbox,开启调试模式(开发环境下会输出详细日志,便于调试)
workbox.setConfig({
  debug: true,
});

// 预缓存指定资源并设置路由:预缓存会在Service Worker安装阶段就缓存资源,确保关键资源离线可用
// 这里预缓存了Bootstrap 4.0.0-beta版本的CSS文件
workbox.precaching.precacheAndRoute([
  'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css',
]);

// 示例1:使用默认缓存策略处理JavaScript文件
// 注册路由,匹配所有以.js结尾的文件(通过正则表达式匹配)
workbox.routing.registerRoute(
  new RegExp('.*\\.(?:js)'),
  // 使用NetworkFirst策略:优先从网络获取资源,网络不可用时使用缓存
  // 适用于频繁更新的资源(如JS文件),保证获取最新版本
  new workbox.strategies.NetworkFirst(),
);

// 示例2:为路由设置自定义缓存名称及插件
// 注册路由,匹配所有图片文件(png、jpg、jpeg、svg、gif格式)
workbox.routing.registerRoute(
  new RegExp('.*\\.(?:png|jpg|jpeg|svg|gif)'),
  // 使用CacheFirst策略:优先从缓存获取资源,缓存未命中时才请求网络
  // 适用于不频繁更新的静态资源(如图片),提升访问速度
  new workbox.strategies.CacheFirst({
    cacheName: 'image-cache', // 自定义缓存名称,便于区分不同类型的缓存
    plugins: [
      // 添加过期插件,限制缓存条目数量最多为3个
      // 当缓存条目超过3个时,会删除最早缓存的条目,防止缓存体积过大
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 3,
      }),
    ],
  }),
);

验证Service Worker是否生效

网络中可查看是否来自service worker

图片[4]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

在应用中可查看缓存空间,版本及已缓存的内容

图片[5]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

如何更新service worker缓存

自动更新,每7天自动更新一次,你可以调整时间

手动更新,修改serviceworker.js文件,图中指示的版本号,修改即可

图片[6]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

结语

哥们儿就问你二次访问快了没?CDN流量是不是消耗的少了?

归档-Service Worker是什么?

Service Worker是一种在浏览器后台独立于网页运行的脚本,它打开了一个能够拦截和处理网络请求、缓存静态资源的强大功能的大门。与以往我们使用的缓存机制不同,Service Worker能更加智能、高效地管理缓存,为用户提供极速的网页加载体验。

归档-Service Worker缓存静态资源逻辑

注册Service Worker,你需要在你的网页中注册一个Service Worker。这通常是通过在JavaScript中调用navigator.serviceWorker.register()方法来实现的。

监听网络请求,在Service Worker中,你可以通过监听fetch事件来拦截网络请求。当浏览器尝试加载一个资源时,Service Worker会先检查该资源是否已经被缓存。

缓存静态资源,如果请求的资源已经被缓存,那么Service Worker会直接返回缓存的资源给浏览器,避免不必要的网络延迟。如果资源尚未被缓存,Service Worker会先请求该资源,并在资源成功加载后将其缓存起来,以便下次快速访问。

简单来说,就是用户在浏览器里面访问过你的网站一次之后,后续访问速度会非常快!

开源地址:https://github.com/GoogleChromeLabs/sw-toolbox

归档-Service Worker缓存带来的优势

提升加载速度,通过缓存静态资源,Service Worker可以大大减少网络请求的响应时间,让用户更快地访问到你的网站。

节省带宽,对于已经被缓存的资源,用户无需再次从服务器下载,从而节省了带宽和服务器资源。

提升用户体验,秒开的网站加载速度无疑会提升用户的满意度和忠诚度,让你的网站在竞争激烈的市场中脱颖而出。

归档-网站接入教程

首先你的网站必须支持https,也就是必须安装ssl证书

这里以wordpress为例,其它网站自己研究,将在文末下载的serviceworker.zip压缩包解压到网站运行目录,压缩包内的三个文件,其中两个(sw-toolbox.js.mapsw-toolbox.js)可以到GitHub下载

在主题function.php添加代码,<script></script>之间的就是js代码,其它网站把js部分加到网站全局生效的地方就行,比如全局顶部,底部,header中等等的,总之加到网站全局生效的部分即可

//将serviceworker引入footer中
function add_sw_footer() {
    ?>
<script>
var serviceWorkerUri = '/serviceworker.js';
if ('serviceWorker' in navigator) { 
navigator.serviceWorker.register(serviceWorkerUri).then(function() {
if (navigator.serviceWorker.controller) {
console.log('成功启动Service Worker缓存');
} else {
console.log('你是第一次访问网站,再次点击一个页面,就会成功启动缓存');
}
}).catch(function(error) {
console.log('ERROR: ' + error);
});
} else {
console.log('当前浏览器不支持Service Worker缓存');
}
</script>
<?php
}
add_action( 'wp_footer', 'add_sw_footer' );

修改serviceworker.js配置文件

静态资源目录添加,比如我发现这个目录下的资源是静态文件,那么就可以添加以下代码到

图片[7]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记
self.toolbox.router.get('/wp-includes/css/dist/block-library/(.*)', self.toolbox.cacheFirst, {
    cache: {
      name: staticAssetsCacheName,
      maxEntries: maxEntries
    }
});

三方静态资源添加,比如此网址下全是静态资源,可以添加该域名

图片[8]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记
self.toolbox.router.get('/(.*)', self.toolbox.cacheFirst, {
    origin: /at\.alicdn\.com/,
    cache: {
      name: staticVendorCacheName,
      maxEntries: maxEntries
    }
});

使用了WP Super Cache插件,会生成静态html,缓存这些html

self.toolbox.router.get('/wp-content/cache/(.*)', self.toolbox.cacheFirst, {
    cache: {
      name: staticAssetsCacheName,
      maxEntries: maxEntries
    }
});

归档-效果展示

网站F12进入开发者工具,可以看到缓存启动,静态资源被缓存到Service Worker,并从Service Worker输出资源

图片[9]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

可以看到,静态资源全部从Service Worker缓存中获取了,而且耗时变成了2毫秒左右,提示ws已经启动

图片[10]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

开始缓存后,完全不去服务器获取静态资源,只去服务器请求一个了一个页面文档。假如你使用了超级缓存插件,并且设置了缓存目录,那么未登录状态下,二次访问速度是极快的。被打开过的页面被缓存到浏览器,就算网站崩了,这个页面还是可以访问的。

归档-如何更新缓存

自动更新,每7天自动更新一次,你可以调整时间

手动更新,修改serviceworker.js文件,图中指示的版本号,修改即可

图片[11]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记
图片[12]-使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记

参考文献:

https://github.com/GoogleChromeLabs/sw-toolbox/issues/207

https://github.com/w3c/ServiceWorker/blob/main/explainer.md

原文链接(非王先生笔记发布均为盗版):https://wxsnote.cn/5220.html

评论后可接收该文章的更新邮箱通知
友情赞助

如果你喜欢我的内容,可以赞助我哦!你的一点点心意,是我不断前进的动力!
温馨提示: 本文最后更新于2024-06-25 22:03:02,某些文章具有时效性,若有错误或已失效,请在下方留言或加入QQ群: 399019539 联系群主反馈。注意一些链接无法访问可能是你网络的原因,如Github,并非资源地址失效。
© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
使用Workbox库的Service Worker缓存静态资源加速你的网站-王先生笔记
使用Workbox库的Service Worker缓存静态资源加速你的网站
此内容为付费资源,请付费后查看
5
限时特惠
10
付费资源
已售 1
相关推荐
评论 共2条

请登录后发表评论

    请登录后查看评论内容

王先生笔记