【问题标题】:Application Cache or Service Workers - which to use in 2016/Q2?应用程序缓存或服务工作者 - 在 2016/Q2 中使用哪个?
【发布时间】:2016-08-11 16:40:23
【问题描述】:

真正的快速讨论问题,因为我想从不同的人那里得到意见。

我正在开发一个必须离线使用的网页应用程序。

现在要做到这一点,据我所知,您可以使用应用程序缓存功能或使用服务工作者。

但是,这是我遇到的难题。在研究应用缓存时,the MDN clearly states

已弃用:
此功能已从 Web 标准中删除。尽管某些浏览器可能仍然支持它,但它正在被删除。不要在旧项目或新项目中使用它。使用它的页面或 Web 应用程序可能随时中断。

之后另一个对话框建议使用服务工作者。

The Service Workers page 然后继续说明 Service Worker 是一种实验性技术,最好查阅兼容性表。

兼容性表显示 Safari 和 Internet Explorer 不支持 Service Worker。进一步咨询this site 并假设它是准确的,它表明微软已经开始整合服务人员,但是对于 Safari,他们正在“考虑中”,并带有“五年计划中的简短积极信号”。

现在这是当前项目的一个问题,因为它必须与 safari 兼容,但是,我也不希望它在其他浏览器中中断。

您有什么建议?只需使用较旧的应用程序缓存并在不久的将来更新?确定用户的浏览器并采取适当的行动?或者,还有其他我想念的方式吗?

【问题讨论】:

    标签: html offline-caching service-worker offlineapps application-cache


    【解决方案1】:

    你说得对,appcache is becoming unsupported

    还有其他选项可以在 IDB 中存储数据和/或资产,例如:

    尝试使用谷歌搜索“offline pouchdb ember”或“offline pouchdb angular”以获取更多示例。

    目前确保离线可用性的唯一机制是 service worker 和 appcache。期间。

    所有这些技术都依赖于您的网站是一个单页应用程序和可访问的入口点。因此,如果您不使用 appcache 或服务工作者来确保入口点始终可访问,则必须回退到 http 缓存并在为您的资产提供服务时正确设置 cache-related headers。无论如何,UA 可以随时驱逐 http 缓存。

    面对这个决定,如果应用程序必须在 Safari 中离线运行,唯一的选择是使用 appcache(AFAIK,没有关于从 Safari 中删除 appcache 的消息)。

    为了降低风险,除了 appcache 之外,您还可以选择结合之前的一种技术(将资产存储在 IndexedDB 上的技术),这样您唯一缓存的就是 SPA 的入口点。如果 appcache 变得不受支持并且没有 service worker 替代方案,您可以切换到缓存标头替代方案。

    无论如何,您可以使用特征检测 (if ('serviceWorker' in navigator) { ... }) 来查看 Service Worker 是否可用,并在可用时使用它。有一个基于服务工作者的 appcache polyfill,名为 JakeCache(未测试)和 others are to come

    【讨论】:

    • 感谢您的帮助,尽管我们已经实现了堆栈,因此无法选择使用 couch db 和 couch db。但是特征检测肯定看起来很有用。谢谢。
    • 我想知道哪些方法适用于自定义元素和 shadow dom。
    【解决方案2】:

    您可以选择在同一个 Web 应用上使用 Service Worker 和 AppCache。在这种情况下,不支持 Service Worker 的浏览器会使用 AppCache,而支持的浏览器会忽略 AppCache,让 Service Worker 接管。

    来源:https://www.w3.org/TR/service-workers/#activation-algorithmhttps://crbug.com/410665

    【讨论】:

    • 我喜欢这里的简单和逻辑。感谢您的建议。
    【解决方案3】:

    绝对可以同时使用两者。如果你想在未来几年部署跨浏览器应用程序,我的印象是你必须继续使用 AppCache,因为 iOS 只是“考虑”在未来 5 年内实现 Service Worker。

    这是我们用来检测是否使用其中一个并初始化两者的一些 JavaScript

    if ( 'serviceWorker' in navigator && b ) {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {
    // Registration was successful
    showMsg('ServiceWorker registration successful with scope: ', registration.scope);
    if ( registration.installing ) {
      showMsg( 'Service worker installing' );
    } else if ( registration.waiting ) {
      showMsg( 'Service worker installed' );
    } else if ( registration.active ) {
      showMsg( 'Service worker active' );
    }
      }).catch(function(err) {
        // registration failed :(
        showMsg('ServiceWorker registration failed: ', err);
      });
    
    // Listen for claiming our ServiceWorker
    navigator.serviceWorker.addEventListener('controllerchange', 
    function(event) {
          // Listen for changes in the state of our ServiceWorker
          navigator.serviceWorker.controller.addEventListener('statechange', function() {
            // If the ServiceWorker becomes "activated", let the user know they can go offline!
            if (this.state === 'activated') {
            // This example is refreshing the app directly, but you can inform the user with a fancy modal window or similar
                window.location.reload( true );
            }
          });
        });
    
    // Browsers not using Service Workers
        } else  if ('applicationCache' in window) {
          var iframe = document.createElement('iframe');
          iframe.style.display = 'none';
          iframe.src = 'load-appcache.html'
          document.body.appendChild(iframe);
          showMsg("Iframe loaded for AppCache management");
    
        } else {
          showMsg("no service worker - no appCache");
    
     }
    

    用于初始化 AppCache 的代码有助于在 appcache 文件更改时刷新新页面。我从多个来源获取了它,但都来自 Patrick Kettner 在 2016 年 PWA 开发者峰会期间发表的强大演示:(https://www.youtube.com/watch?v=IgckqIjvR9U&t=1005s)

    load-appcache.html 只包含

    <!DOCTYPE html>
    <html manifest="offline.appcache">
        <head>
            <title>loding appCache</title>
       </head>
       <body></body>
    </html>
    

    当然,SW 提供了多种可能性来交付更高级的应用程序,但使用 AppCache 和 IDB,您确实可以执行几乎任何您想要的业务逻辑,包括离线功能。

    请注意,您将无法使用 Chrome 测试 AppCache 功能,因为它们已禁用它,但您仍然可以强制使用 Firefox(我已使用 50.1.0 进行了测试)。不过,您始终可以使用 Safari :)

    【讨论】:

    • 就像一个魅力! iFrame 是一个非常好的主意。直到今天,实际的 Chrome 和 Safari 都在做这两个方面:ServiceWorker 缓存和 AppCache,这导致了双倍的有效负载。
    【解决方案4】:

    根据 Mozilla 的 HTML5 Service Workers Doc:

    注意: Service Worker 的一大优点是,如果您使用功能 像我们上面显示的检测,不支持服务的浏览器 工作人员可以按照正常预期的方式在线使用您的应用程序。 此外,如果您在页面上使用 AppCache 和 SW,则不支持的浏览器 支持 SW 但确实支持 AppCache 将使用它,而浏览器 支持两者都会忽略 AppCache,让 SW 接管。

    代码“上面”:

    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw-test/sw.js', {scope: '/sw-test/'})
      .then(function(reg) {
        // registration worked
        console.log('Registration succeeded. Scope is ' + reg.scope);
      }).catch(function(error) {
        // registration failed
        console.log('Registration failed with ' + error);
      });
    }
    

    https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers

    【讨论】:

    • 支持两者的浏览器是否会实际下载“通用”资源两次?
    • 取决于代码。例如,如果您使用 Miguel Guardo 的代码,它将检查 Service Worker 的兼容性。如果浏览器不兼容,脚本将检查 AppCache 的兼容性。如果浏览器不兼容,则脚本终止。
    猜你喜欢
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 2018-06-01
    • 2021-09-21
    • 1970-01-01
    相关资源
    最近更新 更多