javascript - 用谷歌的sw-precache搭建的service worker真的能做到networkFirst吗?

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

我运行网站 https://www.igluonline.com运行 Hugo,我最近在 Google 的 sw-precache 之后安装了一个 service worker .

这是配置文件:

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 处理程序 设置为 networkFirst 并根据 Google 的 sw-toolbox API (当使用 runtimeCaching 时出现在 sw-precache 中)它应该最好从 http 调用中获取页面,如果没有连接它应该回退到缓存。

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

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

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

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

最佳答案

生成服务 worker 时,获取所需策略的最简单方法是使用 sw-precachesw-toolbox .

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

根据sw-precache Documentation :

The sw-precache module has the ability to include the sw-toolbox code and configuration alongside its own configuration. Using the runtimeCaching configuration option in sw-precache (see below) is a shortcut that accomplishes what you could do manually by importing sw-toolbox in your service worker and writing your own routing rules.

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

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

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

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

There's support for passing complex configurations using --config . Any of the options from the file can be overridden via a command-line flag. We strongly recommend passing it an external JavaScript file defining config via module.exports. For example, assume there's a path/to/sw-precache-config.js file that contains:

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

That file could be passed to the command-line interface, while also setting the verbose option, via

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

This provides the most flexibility, such as providing a regular expression for the runtimeCaching.urlPattern option.

或者您可以使用 JSON 文件:

We also support passing in a JSON file for --config, though this provides less flexibility:

{
  "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

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

您可以直接在文件中配置您的策略,也可以在您的服务 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有关配置的更多信息。

关于javascript - 用谷歌的sw-precache搭建的service worker真的能做到networkFirst吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43823725/

相关文章:

c++ - 使用页面文件进行缓存?

Javascript:检查类名是否存在

c# - 如何取消选择列表框中的单个项目

缓存命中、未命中和预测 - 对性能的影响

WCF/Silverlight/SQL 数据库缓存策略

angular - 如何使用 service-worker + angular 修复 'Uncaught (in promise) bad-precaching-response' 错误

javascript - 如何解析 Service Worker 中的 URL

service-worker - Workbox 离线模式仅适用于根路径

javascript - 如何在 Vue 中加载 YAML 文件?

javascript - 如何使解析查找/保存操作同步?