service worker 控制网络请求?

service 特点

1.运行在它自己的全局脚本上下文中

2.不绑定到具体的网页

3.无法修改网页中的元素, 因为它无法访问 dom

4.只能使用 https

Service Worker 是一种在浏览器后台运行的脚本,能够拦截网络请求、管理缓存,并实现离线功能。以下是关于 Service Worker 和离线缓存的核心知识点:

1. Service Worker 基础

  • 独立运行:Service Worker 在独立线程中运行,不影响主线程。

  • 事件驱动:通过事件监听和响应进行操作。

  • HTTPS 要求:生产环境中必须使用 HTTPS,本地开发可通过 localhost127.0.0.1 使用。

2. 生命周期

  • 注册:通过 navigator.serviceWorker.register() 注册。

  • 安装install 事件用于缓存资源。

  • 激活activate 事件用于清理旧缓存。

  • 运行:激活后,Service Worker 可拦截 fetch 事件。

3. 离线缓存实现

  • 缓存资源:在 install 事件中,使用 caches.open()cache.addAll() 缓存资源。

  • 拦截请求:在 fetch 事件中,通过 caches.match() 返回缓存响应,或通过网络获取并缓存新资源。

4. 缓存策略

  • Cache First:优先使用缓存,缓存未命中时请求网络。

  • Network First:优先请求网络,失败时使用缓存。

  • Stale-While-Revalidate:先返回缓存,同时更新缓存。

  • Cache Only:仅使用缓存。

  • Network Only:仅使用网络。

5. 更新与清理

  • 更新 Service Worker:浏览器会检查新版本并触发 install 事件。

  • 清理旧缓存:在 activate 事件中删除旧缓存。

6. 调试

  • Chrome DevTools:通过 Application 面板查看和调试 Service Worker 及缓存。

7. 应用场景

  • 离线访问:缓存关键资源,支持离线使用。

  • 性能优化:通过缓存减少网络请求,提升加载速度。

  • 后台同步:在网络恢复后同步数据。

示例代码

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

// sw.js
const CACHE_NAME = "my-site-cache-v1";
const urlsToCache = ["/", "/styles/main.css", "/script/main.js"];

self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache))
  );
});

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

self.addEventListener("activate", (event) => {
  const cacheWhitelist = [CACHE_NAME];
  event.waitUntil(
    caches.keys().then((cacheNames) =>
      Promise.all(
        cacheNames.map((cacheName) => {
          if (!cacheWhitelist.includes(cacheName)) {
            return caches.delete(cacheName);
          }
        })
      )
    )
  );
});

总结

Service Worker 是实现离线缓存和提升 Web 应用性能的关键工具。通过合理使用缓存策略,可以显著改善用户体验。

如何使用 service worker 提升首屏速度?

使用 Service Worker 提升首屏速度的核心思路是缓存关键资源,减少网络请求的依赖,从而加快页面加载。以下是具体方法和实现步骤:


1. 缓存关键资源

首屏速度的提升依赖于快速加载关键资源(如 HTML、CSS、JavaScript 和字体文件)。可以通过 Service Worker 在安装阶段预缓存这些资源。

实现步骤:

  • install 事件中,将关键资源缓存到 Cache Storage。

  • fetch 事件中,优先从缓存中返回资源。

示例代码:

const CACHE_NAME = "v1";
const urlsToCache = [
  "/", // 首页 HTML
  "/styles/main.css", // 关键 CSS
  "/scripts/main.js", // 关键 JavaScript
  "/images/logo.png", // 关键图片
];

self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache))
  );
});

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

2. 使用缓存优先策略

对于首屏渲染所需的关键资源,可以采用 Cache First 策略,优先从缓存中加载资源,避免网络请求的延迟。

实现步骤:

  • fetch 事件中,先检查缓存中是否存在请求的资源。

  • 如果缓存命中,直接返回缓存内容;否则再发起网络请求。

示例代码:

self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      if (response) {
        return response; // 从缓存返回
      }
      return fetch(event.request); // 从网络请求
    })
  );
});

3. 预加载关键资源

在页面加载时,可以通过 Service Worker 预加载后续页面所需的资源(如其他页面的 HTML 或 JavaScript),从而加快后续页面的加载速度。

实现步骤:

  • fetch 事件中,动态缓存非关键资源。

  • 在页面加载完成后,通过 JavaScript 触发 Service Worker 预加载资源。

示例代码:

self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      if (response) {
        return response; // 从缓存返回
      }
      return fetch(event.request).then((response) => {
        // 动态缓存非关键资源
        if (
          event.request.url.includes("/api/") ||
          event.request.url.includes("/images/")
        ) {
          const responseClone = response.clone();
          caches.open(CACHE_NAME).then((cache) => {
            cache.put(event.request, responseClone);
          });
        }
        return response;
      });
    })
  );
});

4. 优化缓存策略

根据资源类型选择合适的缓存策略:

  • 关键资源:使用 Cache First 策略。

  • 非关键资源:使用 Network First 或 Stale-While-Revalidate 策略。

  • 动态内容:使用 Network First 策略,确保内容最新。

Stale-While-Revalidate 示例:

self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      const fetchPromise = fetch(event.request).then((networkResponse) => {
        // 更新缓存
        caches.open(CACHE_NAME).then((cache) => {
          cache.put(event.request, networkResponse.clone());
        });
        return networkResponse;
      });
      // 返回缓存内容,同时更新缓存
      return cachedResponse || fetchPromise;
    })
  );
});

5. 减少主线程阻塞

Service Worker 可以拦截请求并返回缓存内容,减少主线程的网络请求负担,从而提升页面响应速度。

实现步骤:

  • 将静态资源(如图片、CSS、JavaScript)缓存到 Service Worker。

  • 在页面加载时,直接从缓存中加载资源,避免网络延迟。


6. 结合 HTTP/2 和 Server Push

  • 使用 HTTP/2 的多路复用特性,减少网络请求的开销。

  • 结合 Server Push,将关键资源推送到客户端,进一步提升首屏速度。


7. 调试与监控

  • 使用 Chrome DevTools 的 Application 面板查看 Service Worker 和缓存状态。

  • 使用 Lighthouse 工具分析首屏性能,检查 Service Worker 是否有效提升加载速度。


总结

通过 Service Worker 缓存关键资源、优化缓存策略、预加载资源以及减少主线程阻塞,可以显著提升首屏加载速度。关键在于:

  1. 缓存首屏渲染所需的关键资源。

  2. 使用合适的缓存策略(如 Cache First)。

  3. 动态缓存非关键资源,优化后续页面加载。

通过合理使用 Service Worker,可以大幅提升 Web 应用的性能和用户体验。

最后更新于

这有帮助吗?