当前位置: 首页 > news >正文

Service Worker 离线缓存原理

Service Worker 离线缓存原理

Service Worker 是一种运行在浏览器背后的独立线程,主要用于拦截网络请求、管理缓存以及实现离线访问功能。它是构建 PWA(Progressive Web App,渐进式 Web 应用)不可或缺的一部分。

下面我会详细讲解 Service Worker 离线缓存的原理,包括其工作流程、核心 API 及常见的缓存策略

一、基本原理

Service Worker 本质上是浏览器中的一个脚本,它可以拦截和处理网络请求,从而实现更灵活的资源管理。它运行在主线程之外,不影响页面性能。

离线缓存的核心思想是:

通过 Service Worker 拦截请求,优先从缓存中读取资源,如果没有再从网络请求,并将结果缓存,供下一次使用。

二、注册和生命周期

Service Worker 的生命周期包括以下几个阶段:

1. 注册(register)

在主线程中注册 Service Worker:

if ('serviceWorker' in navigator) {navigator.serviceWorker.register('/sw.js').then(reg => {console.log('Service Worker 注册成功', reg);}).catch(err => {console.error('注册失败:', err);});
}

2. 安装(install)

在安装阶段,通常会预缓存一些关键资源(App Shell):

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

caches 是 Cache API 提供的全局对象,可以创建和访问缓存

3. 激活(activate)

用于清理旧缓存:

self.addEventListener('activate', event => {const cacheWhitelist = ['my-cache-v1'];event.waitUntil(caches.keys().then(cacheNames => {return Promise.all(cacheNames.map(name => {if (!cacheWhitelist.includes(name)) {return caches.delete(name);}}));}));
});

三、拦截请求(fetch 事件)

Service Worker 拦截所有页面请求,可通过各种策略处理缓存:

self.addEventListener('fetch', event => {event.respondWith(caches.match(event.request).then(cachedRes => {// 有缓存就返回,否则请求并缓存return cachedRes || fetch(event.request).then(networkRes => {return caches.open('my-cache-v1').then(cache => {cache.put(event.request, networkRes.clone()); // 克隆一份放缓存return networkRes;});});}).catch(() => {// 如果请求失败(断网),返回默认离线页面return caches.match('/offline.html');}));
});

四、常见缓存策略

策略名称描述
Cache First优先使用缓存,没有则请求网络。适合静态资源(如图片、CSS)
Network First优先请求网络,请求失败再使用缓存。适合内容频繁更新的页面
Stale-While-Revalidate使用缓存的同时异步更新缓存。结合体验与数据新鲜度
Cache Only只用缓存,不请求网络
Network Only只走网络,不用缓存(如登录接口)

五、注意事项

  • Service Worker 只能运行在 HTTPS 或 localhost 下(出于安全考虑)

  • 缓存更新时,必须修改缓存版本号,否则浏览器默认认为旧缓存仍然有效

  • 注意缓存控制策略,避免缓存不一致或缓存污染。

http://www.xdnf.cn/news/125965.html

相关文章:

  • CE第一次作业
  • 基于RK3588/算能BM1684X的智慧厂区AI视觉解决方案
  • BOM与DOM(解疑document window关系)
  • Convenience Variable in GDB
  • 比雅尼·斯特劳斯特鲁普:C++之父
  • SAIL-RK3588协作机器人运动控制器技术方案
  • NestJS 统一异常处理 + 日志追踪链路设计
  • 有关字体,语言,字符编码相关的基础知识,询问chatgpt所得
  • 解决微信开发者工具报错 “Component is not found in path wx://not-found“ 代码修改后热更新报错
  • YOLOv8 涨点新方案:SlideLoss FocalLoss 优化,小目标检测效果炸裂!
  • Android SDK安装和配置
  • 经典算法 区间统计种类
  • YOLOv12的注意力机制革新与实时检测性能分析——基于架构优化与历史版本对比
  • Oracle 11g RAC ASM磁盘组剔盘、加盘实施过程
  • 重构智能场景:艾博连携手智谱,共拓智能座舱AI应用新范式
  • 嵌入式Linux驱动开发:LED实验
  • CAS很好理解
  • WebAssembly:开启高性能Web应用新时代
  • 技术视界 | 数据的金字塔:从仿真到现实,机器人学习的破局之道
  • 使用QML Tumbler 实现时间日期选择器
  • Kubernetes 常用运维命令整理
  • TypeScript 开发实战:如何安全替换字符串中的关键字
  • C#源码分析 --- Random
  • CentOS 7 磁盘阵列搭建与管理全攻略
  • 2. Linux开发工具
  • 系统架构师/软件设计师--选择题概念题口诀与公式计算
  • 如何在windows10上英伟达gtx1060上部署通义千问-7B-Chat
  • 安恒web安全春招实战
  • AI生成内容版权管理:数字时代企业的风险防控与价值保障
  • SEO的关键词研究与优化 第一章