编辑摘要:我创建了一个最小的可重现的例子
我不再相信这与 css 或任何相关@font-face
就此问题作出的声明。问题在于官方的 Angular 方式swUpdate.checkForUpdate()
可能与appRef.isStable
订阅。
我认为现在发生的情况是,Angular 提供的 swUpdate 服务混淆了存在实际更新的想法,即使缓存内容的哈希值保持不变。
我通过更改我的所有 css 文件来解决这个问题angular.json
文件如下所示:
{
"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;
});
});
它仍然提示我更新应用程序。
我读到了两件事——
- 开发工具实际上可能会破坏服务工作线程运行缓存清除的自然循环。
- Angular 建议您通过以下方式订阅他们的可观察事件:
checkForUpdates()
并使用app.isStable
事件触发多次。
我创建了一个最小的可重现的例子并且确实确认了主要的更新问题在于Angular官方文档中更新方法的检查。
simply npm install
然后从 dist 文件夹中运行一个 http-server 实例
http-server -p 4200 -c-1 ./sw-css-test
你就会明白我的意思了!
原帖:
问题 - 在不实际更改任何文件的情况下,服务工作人员认为有更新需要出去获取。
情况:使用配置有可用软件的 Angular 10。导入多个库,例如 Angular Material 等。
理论:Angular 材料尝试出去获取 Google 字体“Roboto”(如果在本地文件树中找不到它),如我捆绑的 style.css 文件中的以下代码片段所示。因为它使用 url() 函数作为后备,所以它会在缓存中查找并找到它,如服务工作人员的 304 响应所示,它未修改。但是,由于 style.css 文件发生了更改(大概是因为它找到了字体?),它会返回 200 响应。然后,这会提示 Service Worker 进行缓存清除,并认为有更新需要出去获取。
一旦你获得更新,冲洗,清洗,重复,你就会有一个无限的更新循环。当您的应用程序有实际更新时,这对于尝试提示用户应该下载是不利的。为什么会发生这种情况?
下面的内容是从捆绑的 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")
}
“网络”选项卡中的片段
![network snippet](https://i.stack.imgur.com/410eQ.png)
我的想法正确吗?
建议的解决方案:找出一种方法来告诉材质库引用 Roboto 的静态版本。
还有其他可能更好的解决方案吗?
供参考我的 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)"
]
}
}
]
}
注意:我尝试从 Service Worker 中删除所有 css 文件以及 ttf、woff 和 woff2 资产。但它仍然带着更新回来了。
任何帮助是极大的赞赏。谢谢。