Service Worker 实现大图懒加载与 WebP 转换,核心是接管请求控制权:1. 拦截图片请求并延迟至视口前1–2秒发起;2. 依Accept头动态切换WebP/原格式并双层降级;3. 分层缓存策略保障性能与容错。
用 service worker 实现大图懒加载与 webp 转换,核心在于把“请求控制权”从浏览器默认行为收归前端逻辑——既推迟非关键图片的加载时机,又按需提供最优格式,还能在失败时自动兜底。
懒加载:靠 SW 拦截 + 缓存预判实现“真延迟”
不同于传统基于 IntersectionObserver 的懒加载(仍需首次触发才发请求),Service Worker 可在用户尚未滚动时就静默拦截并暂缓图片请求,只在图片即将进入视口前 1–2 秒才发起真实网络请求。
- 在 SW 中监听
fetch事件,对匹配/images/.*\.(jpg|jpeg|png)$的请求暂不响应,而是存入待加载队列 - 配合页面中发送的
postMessage消息(例如{type: 'preload-next', index: 3}),SW 主动 fetch 并缓存对应大图 - 当用户真正滚动到该区域,
fetch请求命中缓存,毫秒级返回,无网络等待
WebP 自动适配:靠 Accept 头动态响应
浏览器在请求图片时,会在请求头中带上 Accept: image/webp,*/*(如果支持 WebP)。SW 正是利用这一点做格式协商,无需改 HTML 或后端路由。
- SW 拦截图片请求后,检查
event.request.headers.get('Accept')是否包含image/webp - 若支持,将原请求 URL 的
.jpg替换为.webp,再向服务端发起新请求(或直接从已缓存的 WebP 版本读取) - 若不支持或 WebP 请求失败(如 404),自动 fallback 到原始格式,并缓存该降级结果,避免重复探测
双层降级保障:格式失败 + 网络失败都兜得住
单靠格式切换不够稳健。真实场景中,可能遇到 WebP 文件缺失、CDN 缓存未同步、甚至整个图片服务临时不可用。SW 需覆盖多级容错。
- 第一层:格式降级 —— 请求
photo.webp失败时,立即重试photo.jpg,并将结果写入 cache - 第二层:资源降级 —— 所有图片请求均配置备用占位图(如
/placeholders/lowq-32x32.jpg),确保不白屏 - 第三层:离线兜底 —— 在 install 阶段预缓存一组通用占位图和错误图,即使断网也能渲染基础内容
缓存策略要精细:区分大图、缩略图与占位图
统一缓存所有图片会快速撑爆 Storage API 限额。应按用途分策略管理:
-
大图(原图):使用
cacheFirst策略,有效期设为 7 天,配合 ETag 验证更新 -
缩略图 / 占位图:使用
staleWhileRevalidate,始终优先返回缓存,后台静默更新 - WebP 转换中间态(如 /convert?src=xxx):禁用缓存,由后端控制,避免 SW 缓存脏数据

















