skip to Main Content

I’d like to only have the service worker update check occur eg 5 mins into the app being used.

Problem is that because it’s wrapped in

window.addEventListener('load', async () => {
        navigator.serviceWorker.register("/serviceWorker.js");      
        const registration = await navigator.serviceWorker.getRegistration();

it starts its checks at load time.

To get around it I put the service worker init in a function that I can call whenever I want, but of course, it fails because…

window.addEventListener('load', async ()

was called after the window was loaded.

What’s the general idea for delaying service worker checks?

3

Answers


  1. you can use setTimeout

    function registerServiceWorker() {
      setTimeout(async () => {
        const registration = await navigator.serviceWorker.register("/serviceWorker.js");
      }, 5 * 60 * 1000); 
    }
    
    Login or Signup to reply.
  2. You’ll want to use setTimeout() like this:

    window.addEventListener('load', async () => {
        navigator.serviceWorker.register("/serviceWorker.js");
        setTimeout(async () => {
            const registration = await navigator.serviceWorker.getRegistration();
        }, 300000);
    }
    

    The first parameter to setTimeout() is a callback that is called after the delay, and the second parameter is that delay in milliseconds (5 minutes = 300,000 milliseconds).

    Also, as Arman Charan pointed out, if instead of waiting you want to immediately get the registration, then just await navigator.serviceWorker.register:

    window.addEventListener('load', async () => {
        const registration = await navigator.serviceWorker.register("/serviceWorker.js");
    }
    
    Login or Signup to reply.
  3. I would consider awaiting ServiceWorkerContainer.register().

    The following registerSingletonServiceWorkerUrls implementation demonstrates how to register service worker URLs and retrieve the resulting ServiceWorkerRegistration as needed using Promises.

    /**
     * Registers the given service worker
     * URLs (if not already registered).
     *
     * @returns The resulting value of the current client's
     * `ServiceWorkerContainer`'s `ServiceWorkerRegistration`.
     * 
     * Example use:
     * ```
     * const latestServiceWorkerRegistration = await registerSingletonServiceWorkerUrls(
     *     '/service_worker_1.js',
     *     '/service_worker_2.js',
     * )
     * ```
     */
    function registerSingletonServiceWorkerUrls(
        ...serviceWorkerUrls
    ) {
      return new Promise(
          async resolve => {
            // Wait for the document to finish loading (if applicable):
            while(document.readyState !== 'complete') await tick()
    
            for (const url of serviceWorkerUrls) {
              // Avoid duplicate registrations:
              if (registeredServiceWorkerUrls.has(url)) continue
    
              await navigator.serviceWorker.register(url)
              registeredServiceWorkerUrls.add(url)
            }
    
            const registration = await navigator.serviceWorker.getRegistration()
            return resolve(registration)
          }
      )
    }
    
    let registeredSingletonServiceWorkerUrls = new Set()
    
    function tick() {
      return new Promise(resolve => window.requestIdleCallback(resolve))
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search