2017-07-18 132 views
1

贝娄是我如何注册我的serviceworker:serviceworker`onupdatefound`不会触发移动

if ('serviceWorker' in navigator) { 
    window.addEventListener('load',() => { 
    function updateOnlineStatus() { 
     SnackBar.show({ 
     text: navigator.onLine ? onlineMsg : offlineMsg, 
     backgroundColor: '#000000', 
     actionText: close, 
     actionTextColor: '#d2de2f', 
     customClass: 'custom-snackbar', 
     }); 
    } 
    window.addEventListener('online', updateOnlineStatus); 
    window.addEventListener('offline', updateOnlineStatus); 
    navigator.serviceWorker.register('sw.js').then((reg) => { 
     reg.onupdatefound =() => { 
     const installingWorker = reg.installing; 
     installingWorker.onstatechange =() => { 
      switch (installingWorker.state) { 
      case 'installed': 
       if (navigator.serviceWorker.controller) { 
       SnackBar.show({ 
        text: refreshMsg, 
        backgroundColor: '#000000', 
        actionText: refresh, 
        actionTextColor: '#d2de2f', 
        onActionClick:() => { location.reload(); }, 
        customClass: 'custom-snackbar', 
       }); 
       } else { 
       console.info(availableMsg); 
       } 
       break; 
      case 'redundant': 
       console.info(redundantMsg); 
       break; 
      default: 
       break; 
      } 
     }; 
     }; 
    }).catch((e) => { 
     console.error(errorMsg, e); 
    }); 
    }); 
} 

由针线构建过程中生成此serviceworker。

我有点担心,因为这些通知都显示在我的电脑(Ubuntu的+ chrome 59.0.3071.115),但是从来没有在我的手机(android 6.0.1 + chrome 59.0.3071.125

远程调试功能分析后,它看起来像onupdatefound是永远在我的手机上触发。

我觉得UX很不好,想在移动设备上的游客,将不知道该网站的新版本正在等待...

任何建议或意见可以理解


编辑1:我在本网页的“浏览器兼容性”部分找到了更多详细信息:https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/onupdatefound。 Chrome看起来像支持Android这个功能是未知的。

当浏览器不支持onupdatefound事件时,你们是否有一种回退/解决方法?


编辑2:

<Files sw.js> 
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" 
    Header set Pragma "no-cache" 
    Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT" 
</Files> 

产生:针对杰夫,
sw.js头在.htaccess文件管理

accept-ranges: bytes 
cache-control: max-age=0, no-cache, no-store, must-revalidate 
content-encoding: br 
content-language: fr-FR 
content-length: 1636 
content-type: application/javascript; charset=utf-8 
date: Fri, 21 Jul 2017 13:04:06 GMT 
expires: Wed, 11 Jan 1984 05:00:00 GMT 
last-modified: Tue, 18 Jul 2017 02:58:30 GMT 
pragma: no-cache 

关于箱里微调你的建议,我没有找到时间挖掘,所以我在一个吞咽文件中使用简单的workbox-build。但我希望会:)

// Service Worker generation 
gulp.task('bundle-sw', gulp.series('generate-sitemap',() => { 
    return wbBuild.generateSW({ 
    globDirectory: gulpOutputDir, 
    swDest: `${gulpOutputDir}/sw.js`, 
    globPatterns: ['**/*.{html,png,xml,css,ico,txt,json,svg,js,map,gif,jpeg,jpg,bmp,cur,webp,woff2}'], 
    skipWaiting: true, 
    clientsClaim: true, 
    }) 
    .then(() => { 
    console.warn('Service worker generated.'); 
    }) 
    .catch((err) => { 
    console.error(`[ERROR] This happened: ${err}`); 
    }); 
})); 

你认为这可能是由skipWaiting: true引起的?


编辑3:广播信试图

navigator.serviceWorker.register('/sw.js').then((reg) => { 
    console.log('test'); 
    const updateChannel = new BroadcastChannel('precache-updates'); 
    updateChannel.addEventListener('message', event => { 
    console.log(`Cache updated: ${event.data.payload.updatedUrl}`); 
    }); 
}).catch((e) => { 
    console.error(errorMsg, e); 
}); 

即使test在日志outputed在Chrome,手机,或Firefox,更新消息仅在Chrome

抛出
+0

https://developers.google .com/web/fundamentals/instant-and-offline/service-worker/lifecycle#handling_updates你可能想在修改文档后修改你的观察者。 –

回答

1

应该不会在Android和Linux上的Chrome中的服务工作者实施方面有任何不同,这将考虑到一个平台没有在服务工作者注册中公开updatefound事件。 (MDN在这里不一定是权威的)。

每当我在过去调试过这种不可预测的更新时,都是由于与HTTP缓存和sw.js脚本的交互。你可以检查看看你服务的sw.js你使用的是什么Cache-Control

此外,您提到您正在使用工作箱 - 如果遇到这种情况,您可以使用更高级的方法检查更新的资源。 workbox-broadcast-cache-update插件(如果您使用workbox-swprecache()方法,默认情况下启用)可以宣布何时更新特定的缓存资源,然后您可以使用Broadcast Channel API在您的页面上侦听该消息。这允许您只在最重要的资源发生变化(如HTML)时显示SnackBar,而不是较不重要的资源,例如可能被预先缓存的随机图像。

+0

感谢您花时间!我编辑了OP,提供了与您的观察相关的更多细节 – LIIT

+1

'skipWaiting'和'clientsClaim'都不应阻止触发'updatefound'事件。如果您正在使用'workbox-build',那么生成的'sw.js'将免费获得广播频道API更新。只需在'precache-updates'频道上监听客户端页面的更新即可。请参阅https://workboxjs.org/reference-docs/latest/module-workbox-sw.WorkboxSW.html#properties –

+0

我应用了您的建议(编辑3)。可悲的是,它仍然不适用于手机或Firefox,但它仍然可以在PC的Chrome上运行。我真的很困惑:(但是谢谢你的帮助! – LIIT

1

正如您所怀疑的,问题本身并不是来自服务工作者。

我从头开始,试图找出这个问题的根源,逐个添加代码,直到没有更多的事件暴露。我想通了:这是因为three.js动画中使用的“昂贵”循环。

将这段代码放到工作人员后,我的页面现在可以在移动设备或Firefox上捕获这些事件,并且用户的通知工作得很好!

关于混乱的事实,这是工作在Chrome的桌面版,我想这是因为它必须支持多线程...再次

感谢您的帮助:)

+0

这看起来像一个bug。你有没有向铬队报告? –