src/service-worker.ts

Is run on the browser. The service worker is able to prefetch content (main product image, scripts, fonts, links, etc. as defined here) from within the potential next page’s document. We call this method “deepfetching”. This file is where deepfetching rules are defined: the selector, how many elements, which attribute to fetch, resource type, and an optional callback function for more complex fetches (as shown in the example). Here’s more detailed info about deepfetching .

In case of caching and prefetching elements (from the same origin) with the service worker inside the browser, only those are considered which are matched in routes.ts with a caching configuraton that contains browser caching either by maxAgeSeconds or serviceWorkerSeconds.
As service worker can only prefetch and cache elements (served from the same origin) what's already cached on the edge, prefetching at scale doesn't hurt your origin servers.

By default, the file does the following:

  1. Imports workbox core functionalities, Layer0 Prefetcher, and DeepFetchPlugin for deepfetching :
service-worker.ts
import { skipWaiting, clientsClaim } from 'workbox-core'
import { Prefetcher, prefetch } from '@layer0/prefetch/sw'
import DeepFetchPlugin, { DeepFetchCallbackParam } from '@layer0/prefetch/sw/DeepFetchPlugin'
  1. Prepares the service worker to become active and serve requests:
service-worker.ts
// Forces the waiting service worker to become the active service worker
skipWaiting()
// Uses claim() inside service worker's "activate" event listener so that clients loaded in the same scope do not need to be reloaded before their fetches will go through this service worker.
clientsClaim()
  1. Install Layer0's Deep Fetch Plugin to start prefetching elements from the prefetched pages (or cache elements of the pages that already in the browser cache storage):
service-worker.ts
new Prefetcher({
  plugins: [
    new DeepFetchPlugin([
      {
        // Matches the top 20 script tag
        // in a page, and callbacks to
        // deepFetchAssets for custom prefetching
        selector: 'script',
        maxMatches: 20,
        attribute: 'src',
        as: 'script',
        callback: deepFetchAssets,
      },
      {
        // Matches the top 20 tags that contain
        // the attribute rel="stylesheet"
        // in a page, and callbacks to
        // deepFetchAssets for custom prefetching
        selector: '[rel="stylesheet"]',
        maxMatches: 20,
        attribute: 'href',
        as: 'style',
        callback: deepFetchAssets,
      },
      {
        // Matches the top 20 tags that contain
        // the attribute rel="preload"
        // in a page, and callbacks to
        // deepFetchAssets for custom prefetching
        selector: '[rel="preload"]',
        maxMatches: 20,
        attribute: 'href',
        as: 'style',
        callback: deepFetchAssets,
      },
    ]),
  ],
}).route()
  1. Rely on deepFetchAssets function for custom prefetching. Here's where you can play with element's value(s) before you prefetch them using the service worker:
service-worker.ts
function deepFetchAssets({ $el, el, $ }: DeepFetchCallbackParam) {
  // Grab the href attribute of the element callbacked with
  let urlTemplate = $(el).attr('href')
  // If href attribute exists, prefetch that
  if (urlTemplate) {
    console.log(`\n[][][][]\nPrefetching Asset: ${urlTemplate}\n[][][][]\n`)
    prefetch(urlTemplate)
  }
  // Grab the src attribute of the element callbacked with
  urlTemplate = $(el).attr('src')
  // If src attribute exists, prefetch that
  if (urlTemplate) {
    console.log(`\n[][][][]\nPrefetching Asset: ${urlTemplate}\n[][][][]\n`)
    prefetch(urlTemplate)
  }
}
Edit this page on GitHub Updated at Tue, Jun 21, 2022