Navigation preload

Navigation preload is part of the Service Worker specification. It lets the browser send a “preload” network request for a navigation without blocking on the fetch event handler of the relevant service worker. The service worker will then have access to the preload response inside its fetch event handler. Common use cases are to respond with the preload response directly, or use it to populate the response.

Origin trial

Chrome is experimenting with this feature and it is expected to be available as an origin trial starting in Chrome 57. Origin trials allow you to temporarily enable the feature for users of your website. To use this experimental API in Chrome with no flag, you'll need to request a token for your origin and insert it in your application.

Large sites should NOT enable the feature for all users. Since origin trials are globally shut off if usage exceeds 0.5% of all Chrome page loads, large sites should enable the feature only for a fraction of its users.

If you do experiment with this feature, you can send us feedback at service-worker-discuss or join the spec discussion. In case of a Chrome bug, you can file an issue here. Please include the words "service worker navigation preload" in the issue Summary.

For development purposes, you can also enable the feature locally using --enable-features=ServiceWorkerNavigationPreload starting in Chrome 57.

Sample code

To enable navigation preload, call NavigationPreloadManager.enable(). You can get a NavigationPreloadManager via ServiceWorkerRegistration.navigationPreload. The registration must have an active service worker first.

Inside your service worker:

self.addEventListener('activate', e => {
  if (!self.registration.navigationPreload) {
    // The browser does not support navigation preload.
    return;
  }
  e.waitUntil(self.registration.navigationPreload.enable());
});
Once enabled, a navigation preload request will be sent for navigations inside the service worker's scope. You can access the preload response inside the fetch event for the navigation.

Inside your service worker:

self.addEventListener('fetch', e => {
  if (!e.preloadResponse) {
    // The browser does not support navigation preload.
    return;
  }
  if (e.request.url.endsWith('?use-preload') {
    e.respondWith(e.preloadResponse);
  })
});

Now when you navigate to test.html?use-preload, the service worker will respond with the preload response. See the live demo.

Navigation preload requests also have a ServiceWorkerNavigationPreload HTTP header, whose value defaults to true. You can customize the header value through the NavigationPreloadManager API. See the Service Worker specification for more details.

Links