Posted in

??产品:网络不给力,前端页面就不能展示了吗? – 掘金_AI阅读总结 — 包阅AI

包阅导读总结

1. 关键词:

– Workbox

– Service Worker

– 缓存策略

– 离线支持

– 网页性能

2. 总结:

本文探讨如何利用 Workbox 优化 Service Worker 提升网页性能,包括 Service Worker 的基础知识、生命周期和应用场景,介绍 Workbox 的强大功能、引入方法、插件使用、配置及常用缓存策略,最后总结并期待读者分享处理网络不给力情况的方式。

3. 主要内容:

– 引言

– 提出网页因网络不稳定而存在展示问题,引出优化方案

– Service Worker 基础

– 介绍其概念、运行机制和生命周期的三个阶段

– 列举其主要应用场景

– Workbox 优势

– 由 Google 开发,功能强大,简化缓存管理等

– 引入 Workbox

– 介绍使用 Workbox CLI 和 CDN 两种引入方法

– 使用 Workbox 插件

– 如设置缓存策略

– Workbox 配置

– 预缓存功能

– 路由功能及匹配规则

– 核心的缓存策略

– 总结

– 希望对读者理解 Workbox 有帮助,期待交流

思维导图:

文章地址:https://juejin.cn/post/7397028381974102025

文章来源:juejin.cn

作者:Sailing

发布时间:2024/7/30 2:41

语言:中文

总字数:3222字

预计阅读时间:13分钟

评分:84分

标签:前端开发,Service Worker,Workbox,离线支持,缓存管理


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

引言:产品说:“网络不好,没有网络就不能展示页面了吗?” 前端开发人员****

你是否曾经因为网络不稳定而苦恼?是否希望你的网页在离线时依然能流畅运行?今天,我们将探讨如何利用 Workbox 来优化你的 Service Worker,提升网页性能,确保你的 Web 应用在任何环境下都能稳定运行。

image.png

目前您可能还用不到这篇文章,不过可以先收藏起来。希望将来它能为您提供所需的帮助!

🎈什么是 Service Worker?

在深入了解 Workbox 之前,了解 Service Worker 的基础知识是必要的。Service Worker是运行在浏览器背后的独立线程,用于拦截和处理网络请求、管理缓存和处理推送通知。它的主要目的是增强 Web 应用的离线体验和性能。

Service Worker 在用户访问网页时被安装,并在后台运行,能够在不干扰主页面的情况下执行任务。

Service Worker 的生命周期分为以下3个阶段:

1、安装(Install):当浏览器发现新的 Service Worker 脚本时,会触发 install 事件。在这个阶段,开发者通常会缓存应用的静态资源。

self.addEventListener('install', event => {    event.waitUntil(        caches.open('my-cache').then(cache => {            return cache.addAll([                '/',                '/index.html',                '/styles.css',                '/script.js'            ]);        })    );});

2、激活(Activate):安装完成后,Service Worker 会进入激活阶段。在这个阶段,开发者可以清理旧的缓存,确保新的缓存策略生效。

self.addEventListener('activate', event => {    event.waitUntil(        caches.keys().then(cacheNames => {            return Promise.all(                cacheNames.map(cacheName => {                    if (cacheName !== 'my-cache') {                        return caches.delete(cacheName);                    }                })            );        })    );});

3、运行(Running):激活后,Service Worker 进入运行状态,开始拦截和处理网络请求。开发者可以通过 fetch 事件来控制请求的处理方式。

self.addEventListener('fetch', event => {    event.respondWith(        caches.match(event.request).then(response => {            return response || fetch(event.request);        })    );});

Service Worker主要应用于以下几个场景:

  1. 离线支持:通过缓存静态资源和动态内容,确保应用在没有网络连接时仍然可以使用。
  2. 缓存管理:提高应用性能,通过缓存减少网络请求次数和加快页面加载速度。
  3. 推送通知:Service Worker 可以处理推送通知,即使用户没有打开应用也能接收消息。

手动编写 Service Worker 也可以实现,但是过于复杂,现在有一款比较成熟 npm 库 Workbox。

为什么选择 Workbox?🔥🔥

Workbox 功能强大特性

Workbox 是由 Google 开发的一组库和工具,帮助开发者轻松地将 Service Worker 集成到他们的 Web 应用中。它简化了缓存管理和离线支持,使得 Web 应用能够在没有网络连接的情况下依然保持高性能和可靠性。

主要用途包括:

  • 简化缓存管理:通过预定义的策略自动处理资源的缓存。
  • 提高性能:加快资源加载速度,减少服务器负载。
  • 增强离线功能:确保应用在离线状态下仍能正常运行。
  • 提供插件与扩展:通过各种插件轻松扩展功能,如背景同步、Google Analytics集成等。

与手动编写 Service Worker 的对比,使用 Workbox,开发者只需配置即可,大大提升了开发效率。经过广泛测试和社区验证,提供了高可靠性和性能优化的默认实现。

引入 Workbox(最简单的方法)

引入 Workbox(最简单的方法)可以通过以下几个步骤完成。Workbox 是一个强大的库,用于帮助开发人员简化构建进程中的离线支持和缓存策略。以下是最简单的方法来引入 Workbox:

1. 使用 Workbox CLI

Workbox CLI 是最快速且简单的方式来引入 Workbox 并生成 Service Worker 文件。

  1. 安装 Workbox CLI

    你需要全局安装 Workbox CLI 工具。打开终端并运行以下命令:

    npm install -g workbox-cli
  2. 初始化 Workbox

    在你的项目根目录下,运行以下命令来初始化 Workbox:

    workbox wizard

    这会引导你完成配置过程,并生成一个 workbox-config.js 文件。

  3. 生成 Service Worker

    运行以下命令生成 Service Worker 文件:

    workbox generateSW workbox-config.js

    这将创建一个 service-worker.js 文件,你需要将它注册到你的应用中。

  4. 注册 Service Worker

    在你的应用入口文件(例如 index.jsmain.js)中添加以下代码来注册 Service Worker:

    if ('serviceWorker' in navigator) {  window.addEventListener('load', () => {    navigator.serviceWorker.register('/service-worker.js').then(registration => {      console.log('SW registered: ', registration);    }).catch(registrationError => {      console.log('SW registration failed: ', registrationError);    });  });}

2. 使用 Workbox CDN

如果你不想使用 CLI 工具,你也可以直接通过 CDN 引入 Workbox:

  1. 在 HTML 文件中添加 Workbox 的 CDN 链接

    在你的 HTML 文件的 <head> 标签中添加以下代码:

    <script src="https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js"></script>
  2. 创建和注册 Service Worker

    创建一个 service-worker.js 文件并添加以下代码:

    importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js');workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);

    然后在你的应用入口文件中注册这个 Service Worker:

    if ('serviceWorker' in navigator) {  window.addEventListener('load', () => {    navigator.serviceWorker.register('/service-worker.js').then(registration => {      console.log('SW registered: ', registration);    }).catch(registrationError => {      console.log('SW registration failed: ', registrationError);    });  });}
  3. 使用 Workbox 插件(可选)

    你可以根据需要添加其他 Workbox 插件,例如缓存策略:

    workbox.routing.registerRoute(  ({request}) => request.destination === 'image',  new workbox.strategies.CacheFirst({    cacheName: 'images',    plugins: [      new workbox.expiration.ExpirationPlugin({        maxEntries: 50,        maxAgeSeconds: 30 * 24 * 60 * 60,       }),    ],  }));

Workbox配置

Workbox 预缓存功能

workbox.precaching对象提供了常用的预缓存功能,其中最常用的方法是workbox.precaching.precacheAndRoute。它的作用跟我们前面实现的Precacher.precacheAndRoute()的功能类似, 都是将传入的资源列表进行预缓存,同时对匹配到的预缓存请求直接从本地缓存中读取并返回。

workbox.routing.precacheAndRoute([  {    url: '/index.html',    revision: 'asdf'  },  '/index.abc.js',  '/index.bcd.css'])

Workbox 路由功能全面解析

Workbox 对资源请求匹配和对应的缓存策略执行进行了统一管理,采用路由注册的组织形式,以此来规范化动态缓存。Workbox 提供了简洁的 workbox.routing.registerRoute 方法来注册路由,规范化动态缓存操作。基本用法如下:

workbox.routing.registerRoute(match, handlerCb)

🐱路由匹配规则详解

workbox.routing.registerRoute 的第一个参数 match 是路由匹配规则,支持以下几种匹配模式:

  1. 字符串匹配:对资源 URL 进行字符串匹配。无论是完整 URL 还是相对路径,都可以匹配到相应资源。
workbox.routing.registerRoute('http://127.0.0.1:8080/index.css', handlerCb)workbox.routing.registerRoute('/index.css', handlerCb)workbox.routing.registerRoute('./index.css', handlerCb)

例如,以上注册的路由都能匹配到 http://127.0.0.1:8080/index.css

  1. 正则匹配:对资源 URL 进行正则匹配。
workbox.routing.registerRoute(

这个规则可以匹配以下同域资源:

  • http://127.0.0.1:8080/index.css
  • http://127.0.0.1:8080/a/index.css

但无法匹配跨域资源。为匹配跨域资源需明确指定域名:

workbox.routing.registerRoute(  /^https://third-party-site.com/.*/index.css$/,  handlerCb)
  1. 自定义方法匹配:根据需求实现复杂的资源请求匹配规则。
const match = ({url, event}) => {  return url.pathname === '/index.html'}

match 方法接收 urlevent 参数,其中 urlURL 类实例,eventfetch 事件回调参数。

🐱资源请求处理方法

第二个参数 handlerCb 决定如何响应匹配到的请求,可以从网络、缓存获取资源或在 Service Worker 中直接生成响应。

const handlerCb = ({url, event, params}) => {  return Promise.resolve(new Response('Hello World!'))}

handlerCb 方法接收的对象包含以下属性:

  • url:经过 URL 类实例化的 event.request.url
  • eventfetch 事件回调参数。
  • params:自定义匹配方法返回的值。

注意handlerCb 必须是异步函数,返回一个 Promise,该 Promise 的解析结果必须是一个 Response 对象。

Workbox 的路由功能通过统一管理资源请求匹配和缓存策略,显著提升了前端开发的效率和用户体验。

Workbox缓存策略(🔥🔥核心点,非常重要)

Workbox 提供了一系列灵活且强大的缓存策略,帮助开发者优化Web应用的性能。以下是几种常用的缓存策略以及它们的详细说明和应用场景:

  • NetworkFirst:网络优先
  • CacheFirst:缓存优先
  • NetworkOnly:仅使用正常的网络请求
  • CacheOnly:仅使用缓存中的资源
  • StaleWhileRevalidate:从缓存中读取资源的同时发送网络请求更新本地缓存
const {NetworkFirst, CacheFirst, StaleWhileRevalidate} = workbox.strategies;workbox.routing.registerRoute(/\api/, new workbox.strategies.NetworkFirst())

Stale-while-revalidate

当请求的路由有对应的 Cache 缓存结果就直接返回,在返回 Cache 缓存结果的同时会在后台发起网络请求拿到请求结果并更新 Cache 缓存,如果本来就没有 Cache 缓存的话,直接就发起网络请求并返回结果,这对用户来说是一种非常安全的策略。

  1. 在第一次请求获取资源时,从网络中提取资源,将其放入缓存中并返回网络响应。
  2. 对于后续请求,首先从缓存提供资源,然后“在后台”从网络重新请求该资源,并更新资源的缓存条目。
  3. 对于此后的请求,您将收到在上一步中从缓存中放置的最后一个网络提取的版本。

image.png

Cache First

当匹配到请求之后直接从 Cache 缓存中取得结果,如果 Cache 缓存中没有结果,那就会发起网络请求,拿到网络请求结果并将结果更新至 Cache 缓存,并将结果返回给客户端。这种策略比较适合结果不怎么变动且对实时性要求不高的请求。

image.png

Network First

优先尝试拿到网络请求的返回结果,如果拿到网络请求的结果,就将结果返回给客户端并且写入 Cache 缓存,如果网络请求失败,那最后被缓存的 Cache 缓存结果就会被返回到客户端,这种策略一般适用于返回结果不太固定或对实时性有要求的请求,为网络请求失败进行兜底。

image.png

Cache Only

始终从缓存中获取资源,不发起网络请求。

image.png

Network Only

始终从网络请求资源,不使用缓存。

image.png

扩展延伸:Workbox自定义策略

在某些情况下,您可能希望使用自己的其他策略来响应请求,或者只是通过模板在 Service Worker 中生成请求。
为此可以提供一个异步返回Response对象的函数handler

const handler = async ({ url, event }) => {  return new Response(`Custom handler response.`);};workbox.routing.registerRoute(new RegExp(matchString), handler);

需要注意的是,如果在match回调中返回一个值,它将handler作为params参数传递到回调中。

const match = ({ url, event }) => {  if (url.pathname === '/example') {    return {      name: 'Workbox',      type: 'guide',    };  }};const handler = async ({ url, event, params }) => {    return new Response(`A ${params.type} to ${params.name}`);};workbox.routing.registerRoute(match, handler);

如果 URL 中的某些信息可以在 match 回调中解析一次并在中使用,则这可能会对handler有所帮助。

总结

希望这篇文章对你理解使用 Workbox 功能有所帮助。如果你有任何疑问或见解,欢迎在评论区分享或提问,让我们共同进步!

你打算如何在项目中处理网络不给力的情况呢?期待你的留言!