【问题标题】:Is pre-fetching assets in Service Workers really the best idea?在 Service Worker 中预取资产真的是最好的主意吗?
【发布时间】:2017-11-09 02:19:50
【问题描述】:

我见过的所有使用 Service Worker 的离线 Web 应用程序示例都包括以下模式以在安装时预获取其资产:

self.addEventListener('install', function(event) {
  event.waitUntil(caches.open('assets').then(function(cache) {
      return cache.addAll([
        '/',
        '/static/all.css',
        '/static/script.js',
        ...
      ])
    }));
});

但是,我在使用这种方法时遇到了以下问题:

  1. 首次加载时,资源会被提取两次,一次是在初始页面加载期间(在 Service Worker 处于活动状态之前),另一次是安装 Service Worker。
  2. 安装期间预取的响应是否可能会自动从缓存中删除(当网站有一段时间未访问或存储空间不足时)?
  3. 编译和维护完整的资产列表很麻烦。有时甚至是不可能的,例如使用 Google 字体时,只知道 CSS 的位置,但字体本身的位置会因浏览器而异,并且可能会发生变化。

或者,我可以在第一次请求资产时缓存它们,这将消除上述问题。但是这样显然不能保证在用户离线时缓存已经被填充。通过Link 标头注册 Service Worker 可能会缓解这种情况,使其在请求资产时可能运行。当然,这仅适用于单页应用程序,在每个页面视图上都请求所有资源。

或者有没有更好的做法?

【问题讨论】:

    标签: javascript service-worker


    【解决方案1】:

    我建议使用像 Workbox(我正在研究)或 offline-plugin 这样的工具来自动生成要预缓存的资产列表。

    我还建议在服务工作者注册时关注these best practices,这会将注册推迟到您的页面加载其初始内容之后。

    此时,您可以告诉您的 Service Worker 为永不更改的资产提供 HTTP 缓存(在工作箱中,这是使用 dontCacheBustUrlsMatching configuration parameter 完成的),并且您最终不会重新下载那些资产。某些资产无法安全地从 HTTP 缓存中读取,例如大多数 HTML 文档,这些资产最终会被下载两次。

    【讨论】:

    • 当然,我可以依靠Cache-Control HTTP 标头来避免重新下载资产。但我想知道这是否真的是最佳做法。就我而言(单页应用程序),我什至可以将服务器设置为缓存 HTML 一段时间,但对于大多数其他网站来说,这不起作用。此外,我仍然不知道如何解决 Google 字体问题。即使我预先获取其他所有内容,我仍然必须确保在下载字体时 Service Worker 正在运行,以便动态缓存它。
    • 第一次访问后,可以通过运行时缓存获取“不可预测”的 URL,例如 Google 字体所需的 URL。另请参阅github.com/GoogleChrome/workbox/issues/368,了解在第一次访问期间解决此问题的潜在方法。
    • 感谢 Workbox 的推荐!通过使用它,我能够真正提高我的服务人员。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多