簡體   English   中英

Service Worker 更新事件觸發器

[英]Service worker update event trigger

按照此鏈接https://github.com/deanhume/pwa-update-available ,我正在嘗試實現服務工作者更新,但我遇到了諸如事件更新未觸發之類的問題,我認為這與我的應用程序設計,基本上是一個 SPA,意味着我總是在 index.html,它的行為類似於 app-shell,我正在推送內容區域中的內容,具體取決於單擊哪個按鈕。

只有其他頁面是登錄/索引。html

app.js 安裝/更新 service worker 的內容是這樣的:

let newWorker;
          function showUpdateBar() {
            let snackbar = document.getElementById('snackbar');
            snackbar.className = 'show';
          }
          // The click event on the pop up notification
          document.getElementById('reload').addEventListener('click', function(){
            newWorker.postMessage({ action: 'skipWaiting' });
          });
          if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/pwa/sw.js').then(reg => {
              console.log( 'ServiceWorker registration successful with scope: ', registration.scope );
              reg.addEventListener('updatefound', () => {
                // A wild service worker has appeared in reg.installing!
                newWorker = reg.installing;
                newWorker.addEventListener('statechange', () => {
                  // Has network.state changed?
                  switch (newWorker.state) {
                    case 'installed':
                      if (navigator.serviceWorker.controller) {
                        // new update available
                        showUpdateBar();
                      }
                      // No update available
                      break;
                  }
                });
              });
            });
            let refreshing;
            navigator.serviceWorker.addEventListener('controllerchange', function () {
              if (refreshing) return;
              window.location.reload();
              refreshing = true;
            });
          }  

和 sw.js 文件內容是這樣的:

var cacheName = 'v28';

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(cacheName)
      .then(cache => cache.addAll([
        "/pwa/index.html",
        "/pwa/main.css",
        "/pwa/js/app/app.js",
        "/pwa/js/app/libs/api.js",
        '/pwa/query.js',
        '/pwa/js/libs/localforage.min.js',
        '/pwa/js/libs/utils.js'
      ]))
  );
});



self.addEventListener('message', function (event) {
  if (event.data.action === 'skipWaiting') {
    self.skipWaiting();
  }
});

// Allow sw to control of current page
self.addEventListener('activate', event => {
  console.log('Activating new service worker...');

  const cacheWhitelist = [cacheName];

  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

index.html 的部分內容:

<div id="snackbar">A new version of this app is available. Click <a id="reload">here</a> to update.</div>

所以基本上我面臨的問題是,觸發更新,當我將版本號(如 v28 更改為 v29 並重新加載頁面時)我收到提示,但即使我注銷、登錄或退出時也沒有收到提示並重新打開應用程序。

我該如何解決這個問題?

注意:PWA 是我的漸進式應用程序文件夾,我使用 php/yii2 作為后端,而不是使用節點服務器或其他 JS 框架。

僅當您在瀏覽器中加載 index.html 時才會觸發服務工作者注冊例程。 這是代碼執行的唯一時間。

除非您定期輪詢您的服務器或可能打開 websocket(為此有點貴),否則您不會知道是否有新的 service worker 可用。 你可以讓用戶注冊推送通知……這太讓人頭疼了。

因此,每隔幾個小時或幾天將服務器匯集一次以進行更新。

如果有更新,您可以觸發更新例程。

我會將輪詢邏輯放在實際的服務工作者代碼中以使其遠離 UI,如果您是 SPA,那么您已經足夠鎖定 UI 線程了。

有很多方法可以給這只貓剝皮,setTimeout(..., {lots of seconds}),當服務工作者從休眠中醒來時等等。

如果您可以發出 HEAD 請求,將網絡流量保持在最低限度。

如果有更新,您可以向 UI 發布消息以更新 service worker。

這不是我所說的瑣碎代碼。 我做了類似的事情來保持我的緩存資產是最新的,所以我一直在那里:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM