【问题标题】:Can a service worker built with Google's sw-precache really be networkFirst?使用 Google 的 sw-precache 构建的 service worker 真的可以成为 networkFirst 吗?
【发布时间】:2017-05-06 18:00:40
【问题描述】:

我运行着运行 Hugo 的网站 https://www.igluonline.com,最近我按照 Google 的 sw-precache 安装了一个服务工作者。

这是配置文件:

module.exports = {
  staticFileGlobs: [
    'dist/css/**.css',
    'dist/**/*.html',
    'dist/images/**.*',
    'dist/js/**.js'
  ],
  skipWaiting: true,
  stripPrefix: 'dist',
  runtimeCaching: [{
    urlPattern: /\/*/,
    handler: 'networkFirst'
  }]
};

注意事项:

虽然有时自动生成的代码会出现一些错误,但 Service Worker 可以正常工作并在 Web 和移动设备上提供离线体验。

它还将cache-control 设置为max-age=0,当我推送新代码时,它会进行更新。

问题:

我将runtimeCaching handler 设置为networkFirst 并根据Google 的sw-toolbox API(使用runtimeCaching 时出现在sw-precache 中)它应该最好从http 调用中获取页面,如果有没有连接,它应该回退到缓存。

但是当我刷新我的代码并打开一个新窗口进行测试时(请注意,我确实在更新之前关闭了运行该网站的所有选项卡和窗口),它将显示缓存页面。它自然会下载新的 service worker 并在第二次重新加载时更新页面,但我不希望我的访问者每次都刷新我的主页以获取新内容。

我尝试将runtimeCachingcode 更改为以下代码,希望至少可以直接从网络加载我的主页,但我没有运气:

runtimeCaching: [{
    urlPattern: /\//,
    handler: 'networkOnly'
  },{
    urlPattern: /\/*/,
    handler: 'networkFirst'
  }]

现在我不确定所需的 PWA 体验是否是这样的 - 这意味着用户必须重新加载两次或至少访问两个页面才能看到刷新的代码 - 或者我是否犯了一些错误。我真的很感激考虑。

【问题讨论】:

  • 问题是在加载您的站点时用户总是获得缓存版本,还是当您更新 Service Worker 时,用户在加载第二个页面之前看不到新的 Service Worker 更改?跨度>
  • @abraham,感谢您的评论。那将是第二种选择。例如,当我用新文章更新我的网站时(因此是工作人员),用户在第二次加载同一页面或网站上的任何其他页面之前不会看到更改。
  • 可能重复,因为这似乎与此处描述的同一问题有关:stackoverflow.com/questions/41422474/…
  • @lax1089 感谢您的链接,但这个问题是我在网上发现的第一个关于该问题的问题。那里的解决方案指定了最大年龄,不幸的是这不是我要解决的问题。我想我会认为 sw-prechace 是有缺陷的。

标签: javascript caching service-worker progressive-web-apps sw-precache


【解决方案1】:

在生成 service-workers 时,获得所需策略的最简单方法是使用 sw-precachesw-toolbox

在使用sw-precache 生成新的 service-worker 时,您还可以通过传递正确的配置选项来获取生成文件末尾的sw-toolbox 代码。

根据sw-precache Documentation

sw-precache 模块能够将sw-toolbox 代码和配置与自己的配置一起包含。在sw-precache (see below) 中使用runtimeCaching 配置选项是一种快捷方式,可以通过在您的服务工作者中导入sw-toolbox 并编写您自己的路由规则来完成您可以手动执行的操作。

这是sw-precache documentation 上显示的runtimeCaching 选项的示例:

runtimeCaching: [{
  urlPattern: /^https:\/\/example\.com\/api/,
  handler: 'networkFirst'
}, {
  urlPattern: /\/articles\//,
  handler: 'fastest',
  options: {
    cache: {
      maxEntries: 10,
      name: 'articles-cache'
    }
  }
}]

您可以将此选项与您选择的配置一起使用。

例如,您可以使用documentation 中所述的配置文件:

支持使用 --config 传递复杂的配置。文件中的任何选项都可以通过命令行标志覆盖。我们强烈建议通过 module.exports 将定义配置的外部 JavaScript 文件传递​​给它。例如,假设有一个 path/to/sw-precache-config.js 文件包含:

module.exports = {
  staticFileGlobs: [
    'app/css/**.css',
    'app/**.html',
    'app/images/**.*',
    'app/js/**.js'
  ],
  stripPrefix: 'app/',
  runtimeCaching: [{
    urlPattern: /this\\.is\\.a\\.regex/,
    handler: 'networkFirst'
  }]
};

该文件可以传递到命令行界面,同时也 设置详细选项,通过

$ sw-precache --config=path/to/sw-precache-config.js --verbose

这提供了最大的灵活性,例如为 runtimeCaching.urlPattern 选项提供正则表达式。

或者您可以使用 JSON 文件:

我们还支持为 --config 传递 JSON 文件,尽管这提供的灵活性较低:

{
  "staticFileGlobs": [
    "app/css/**.css",
    "app/**.html",
    "app/images/**.*",
    "app/js/**.js"
  ],
  "stripPrefix": "app/",
  "runtimeCaching": [{
    "urlPattern": "/express/style/path/(.*)",
    "handler": "networkFirst"
  }]
}

本示例使用 JS 文件进行配置选项:

$ sw-precache --config=path/to/sw-precache-config.js --verbose

执行命令并使用此配置生成 service-worker 后,您可以比仅使用 sw-precache 更轻松地处理预缓存和策略。

您可以直接在文件中配置您的策略,或者在您的 service-worker 代码底部手动添加它们。

下面是生成代码底部的例子:

//sw-precache generated code...

// *** Start of auto-included sw-toolbox code. ***
/*
 Copyright 2016 Google Inc. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/ 
//(!function(e){if("object"==typeof exports&&"undefined"!=typeof module))...

// *** End of auto-included sw-toolbox code. ***

// Runtime cache configuration, using the sw-toolbox library.

toolbox.router.get(/this\\.is\\.a\\.regex/, toolbox.networkFirst, {});

toolbox.options.debug = true;

//Here you can configure your precache:

toolbox.precache([
    '/',
    '/assets/background.png',
    '/assets/logo.png',
    '/assets/application.css',
]);

//And here you can configure your policies for any route and asset:

toolbox.router.get('/', toolbox.fastest);
toolbox.router.get('/assets/background.png', toolbox.fastest);
toolbox.router.get('/assets/logo.png', toolbox.fastest);

//Here is the Network First example

toolbox.router.get('/myapp/index.html', toolbox.networkFirst);

我发现这比仅使用 sw-precache 更加有效和灵活。

您可以在此处找到sw-toolbox Usage Guide,了解有关配置的更多信息。

【讨论】:

    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多