You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Service Worker在Safari登出后卡顿问题排查求助

iPhone Safari下Angular PWA登出卡顿的排查与解决

问题背景

基于Angular 14的PWA应用,部署在Azure Blob Storage静态网站,使用Azure AD B2C + MSAL实现认证。调用msalService.logoutRedirect()时,仅iPhone Safari在锁屏数分钟后会出现浏览器冻结、持续网络请求的卡顿问题,禁用Angular Service Worker(SW)后恢复正常,推测与SW处理第三方字体缓存有关。

核心排查与解决方案

1. 修复谷歌字体的SW缓存配置

当前ngsw-config.json未包含跨域的谷歌字体资源,Angular SW默认不缓存跨域内容。锁屏后Safari可能清理了系统缓存,SW拦截字体请求时找不到缓存,陷入无限重试循环。

修改ngsw-config.json,添加dataGroups配置专门处理谷歌字体:

{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    // 原有的assetGroups配置保持不变
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/manifest.webmanifest",
          "/*.css",
          "/*.js"
        ]
      }
    }, {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ],
  // 新增dataGroups处理谷歌字体
  "dataGroups": [
    {
      "name": "google-fonts",
      "urls": [
        "https://fonts.googleapis.com/**",
        "https://fonts.gstatic.com/**"
      ],
      "cacheConfig": {
        "maxSize": 50,
        "maxAge": "7d",
        "strategy": "freshness"
      }
    }
  ]
}
  • freshness策略优先尝试网络请求,失败时回退到缓存,避免SW因缓存缺失卡住;同时明确允许缓存跨域字体资源。

2. 登出流程中临时绕过SW

针对Safari环境,在执行登出前临时注销SW,避免其干扰登出跳转流程:

async logout() {
  // 检测是否为Safari浏览器
  if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
    const registration = await navigator.serviceWorker.getRegistration();
    if (registration) {
      // 临时注销SW
      await registration.unregister();
    }
  }
  this.msalService.logoutRedirect();
}
  • 用户从登出页面返回时,SW会自动重新注册,不影响PWA的正常功能。

3. Safari专属SW调试技巧

无需直接调试2000行的ngsw-worker.js,用远程调试提前监控请求:

  • 开启iPhone的「设置」→「Safari浏览器」→「高级」→「Web检查器」
  • Mac端Safari开启「开发」菜单,选择对应iPhone设备的应用页面,实时监控SW的fetch事件日志
  • 提前在构建后的ngsw-worker.js中添加日志(位于dist目录):
    // 在fetch事件处理开头添加
    self.addEventListener('fetch', (event) => {
      console.log('SW处理请求:', event.request.url);
      // 原有代码保持不变
    });
    
  • 卡顿发生时,通过远程控制台确认是否卡在谷歌字体的请求上。

4. 缓存状态验证的替代方法

当ngsw/state无法访问时,用代码主动检查SW缓存内容:

async checkSWCache() {
  const cache = await caches.open('ngsw:assets:cache');
  const cachedUrls = (await cache.keys()).map(key => key.url);
  console.log('SW缓存的资源:', cachedUrls);
}
  • 在应用正常状态下执行,确认谷歌字体是否被正确缓存,以及锁屏后是否被清理。

内容的提问来源于stack exchange,提问作者killexe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 08:36:26