Angular V10服务工作者官方更新方法不工作

发布于 2025-01-18 04:48:36 字数 4236 浏览 1 评论 0原文

编辑摘要:我已经创建了一个最小的 reproducible示例

我不再相信这是与CSS或任何@font-face声明有关。问题在于swupdate.checkforupdate()的官方角度方法可能与appref.isstable subscription结合使用。

我认为现在正在发生的是,Angular提供的SWUPDATE服务正以为存在实际更新,即使缓存内容的哈希值保持不变。

我通过在angular.json.json文件中更改所有CSS文件来弄清楚这一点:

{
   "input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
   "bundleName": "material-theme",
   "inject": false
}

然后我做了一个简单的服务,将捆绑的样式表添加到我的标题中。我可以在任何时间点添加它们,甚至选择在加载应用程序后几分钟将它们添加(以及下面的Swupdate事件发射了多个不同的时间)。

    const appIsStable$ = this.appRef.isStable.pipe(takeWhile(isStable => isStable === true));
    const everyMinute$ = interval(60*1000);
    const swUpdateCheck$ = concat(appIsStable$, everyMinute$);

    swUpdateCheck$.subscribe(() => {
      console.log('update check');
      this.swUpdate.checkForUpdate().then(() => {
        console.log('new version available');
        if(this.window.confirm('New version available. Click OK to download')){
          this.swUpdate.activateUpdate().then(() => {
            this.window.location.reload();
          });
        }
      }, (rej) => {
        debugger;
      });
    });

它仍然给我提示更新应用程序。

我读过的两件事 -

  1. DevTools实际上可能会分散服务人员如何进行缓存的自然周期。
  2. Angular建议您通过ChectForupDates()和使用app.isstable事件多次触发的方式。

我已经创建了一个最小的可重现的示例并确实确认了主要更新问题在Angular的官方文档中检查更新方法的谎言。

只需npm install然后从DIST文件夹中运行HTTP-Server实例

http-server -p 4200 -c-1 ./sw-css-test

,您将看到我的意思!

原始帖子:

问题 - 没有物理更改任何文件,服务人员认为有一个更新需要出去并获取。

情况:使用与SW可用的Angular 10。 该理论: Angular

材料试图出去并获取Google字体“ Roboto”(如果在本地文件树中找到它),请从我的捆绑中指出style.css文件。因为它将URL()函数用作后备,所以它可以在缓存中寻找并找到它,如服务工作者的304响应所示,未修改。但是,因为style.css文件更改(大概是因为它找到了字体?),所以它带有200个响应。然后,这提示了服务工作者的缓存破坏,并认为有一个更新需要出去。

获得更新后,冲洗,清洗,重复,您会有一个无限的更新循环。当您应该下载的应用程序的实际更新时,尝试提示用户尝试提示用户。为什么会发生这种情况?

以下从捆绑的CSS中剪断。

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 400;
    src: local("Roboto"),local("Roboto-Regular"),url(roboto-v20-latin-ext_latin-regular.5cb5c8f08bb4e6cb64c3.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-regular.ae804dc012b1b5255474.woff) format("woff")
}

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 500;
    src: local("Roboto Medium"),local("Roboto-Medium"),url(roboto-v20-latin-ext_latin-500.0b45721325446d537b54.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-500.e492ac63197a57e7f4d3.woff) format("woff")
}

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 700;
    src: local("Roboto Bold"),local("Roboto-Bold"),url(roboto-v20-latin-ext_latin-700.1d1ef7788f0ff084b881.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-700.8aba6dc5d991e4367d7a.woff) format("woff")
}

snippet来自“网络”选项卡

“网络摘要”

我在这里沿着正确的行思考吗?

提出的解决方案:找出一种告诉材料库引用静态版本的方法。

还有其他解决方案可能更好吗?

有关我的NGSW-CONFIG.JSON:

{
  "$schema": "../node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "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)"
        ]
      }
    }
  ]
}

注意:我尝试从服务工作者中删除所有CSS文件以及TTF,WOFF和WOFF2资产。然而,它仍然带有更新。

任何帮助将不胜感激。谢谢。

Edit Summary: I've created a minimal reproducible example

I no longer believe this is related to css or any @font-face declaration for that matter. The problem lies with the official Angular way of swUpdate.checkForUpdate() possibly in conjunction with appRef.isStable subscription.

What I believe is happening now is that the swUpdate service provided by angular is messing up with thinking that there is an actual update, even though hashed values of cached content remain the same.

I figured this out by changing all of my css files in my angular.json file to look like the following:

{
   "input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
   "bundleName": "material-theme",
   "inject": false
}

then I made a simple service to add the bundled style sheets to my header. I could add them at any point in time, even choosing to add them minutes after the application loaded (and the swUpdate event below fired multiple different times).

    const appIsStable$ = this.appRef.isStable.pipe(takeWhile(isStable => isStable === true));
    const everyMinute$ = interval(60*1000);
    const swUpdateCheck$ = concat(appIsStable$, everyMinute$);

    swUpdateCheck$.subscribe(() => {
      console.log('update check');
      this.swUpdate.checkForUpdate().then(() => {
        console.log('new version available');
        if(this.window.confirm('New version available. Click OK to download')){
          this.swUpdate.activateUpdate().then(() => {
            this.window.location.reload();
          });
        }
      }, (rej) => {
        debugger;
      });
    });

It still gives me my prompt to update the application.

There are 2 things I read about this -

  1. Devtools might actually be distrupting the natural cycle of how the service worker runs cache-busting.
  2. The way that Angular recommends you to subscribe to their observable event via checkForUpdates() and using an app.isStable event fires multiple times.

I've created a minimal reproducible example and have indeed confirmed that the main update problem lies with the checking for update methodology in Angular's official docs.

simply npm install then run a http-server instance like so from the dist folder

http-server -p 4200 -c-1 ./sw-css-test

And you'll see what I mean!

Original Post:

The Problem - Without physically changing any file, the service worker thinks there is an update to go out and get.

The Situation: Using Angular 10 configured with SW available. Multiple libraries imported such as Angular Material, etc.

The Theory: Angular material tries to go out and get the Google font 'Roboto' (if it can't find it in the local file tree) as noted in the following snippet from my bundled style.css file. Because it is using the url() function as a fallback, it goes to look for this in the cache and finds it, UNMODIFIED as indicated from the 304 response from the service worker. However, because the style.css file changed (presumably because it found the font?) it comes back with a 200 response. This then prompts cache busting of the service worker and it thinks that there is an update to go out and get.

Once you get the update, rinse, wash, repeat, and you have an infinite update loop. This is bad for trying to prompt a user when there is an actual update of your app that they should go download. Why is this happening?

The below snipped from the bundled css.

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 400;
    src: local("Roboto"),local("Roboto-Regular"),url(roboto-v20-latin-ext_latin-regular.5cb5c8f08bb4e6cb64c3.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-regular.ae804dc012b1b5255474.woff) format("woff")
}

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 500;
    src: local("Roboto Medium"),local("Roboto-Medium"),url(roboto-v20-latin-ext_latin-500.0b45721325446d537b54.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-500.e492ac63197a57e7f4d3.woff) format("woff")
}

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 700;
    src: local("Roboto Bold"),local("Roboto-Bold"),url(roboto-v20-latin-ext_latin-700.1d1ef7788f0ff084b881.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-700.8aba6dc5d991e4367d7a.woff) format("woff")
}

Snippet from the Network tab

network snippet

Am I thinking along the right lines here?

The Proposed Solution: Figure out a way to tell the material library to reference a static version of Roboto.

Is there any other solution that might be better?

For reference my ngsw-config.json:

{
  "$schema": "../node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "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)"
        ]
      }
    }
  ]
}

Note: I have tried removing all css files and ttf, woff, and woff2 assets from the service worker. Yet it still comes back with an update.

Any help is greatly appreciated. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空袭的梦i 2025-01-25 04:48:36

您是否尝试过查看 v10特定文档并确保它是正如您所描述的那样工作?

无论如何,即使有更新,承诺总是可以解决的。尝试使用可用checkforupdate()一起观察?

另外,尝试将清单文件从ngsw-config.json中提取出来,看看是否也没有帮助。我以前看过哈希不匹配该文件。

ngsw/state的输出在您的config.url说什么?

Have you tried looking at the v10 specific documentation and checking to make sure it is working as you are describing above?

It looks like the promise always resolves no matter what - even if there is an update or not. Try using the available observable in conjunction with checkForUpdate()?

Also, try pulling your manifest file out of the ngsw-config.json and see if that doesn't help as well. I've seen hash mismatching in that file before.

What does the output of ngsw/state after your config.url say?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文