Skip to content

explainers-by-googlers/service-worker-synthetic-response

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Explainer for Service Worker Synthetic Response

This proposal is an early design sketch by Google Chrome Loading team to describe the problem below and solicit feedback on the proposed solution. It has not been approved to ship in Chrome.

Authors

Proponents

  • Google Chrome Loading team

Participate

Table of Contents

Introduction

The Service Worker Static Routing API (https://github.com/WICG/service-worker-static-routing-api) provides a mechanism to bypass Service Worker bootstrap by declaratively routing requests. While this solves the "Service Worker Startup" tax, navigation performance is still limited by network latency.

Currently, even with a static route, the browser process must wait for the first bytes of a network response before it can create/find a renderer process and commit the navigation. This "Network-to-Commit" gap can often take hundreds of milliseconds.

Service Worker Synthetic Response extends the Static Routing API to eliminate this gap. It allows the browser to immediately serve a cached "synthetic" response (like an App Shell) to trigger the renderer commit phase instantly, while the dynamic content is fetched from the network in the background.

Goals

  • Early Navigation Commit: Trigger the renderer's commit phase immediately using cached data, without waiting for a network round-trip.
  • Parallelize Renderer Initialization and Network Fetch: Overlap the time spent setting up the renderer process with the time spent waiting for the server.
  • Improved Loading Metrics: By committing the static part of the response immediately, the browser can start initializing the renderer process, which includes the document creation or JavaScript engine startup. This results in parsing resources (CSS/JS) and painting the UI sooner.

Non-goals

  • Handling Non-GET Requests: The synthetic response mechanism is intended for navigation requests (requestMode: "navigate"), which are primarily GET requests. Handling POST or other non-idempotent methods is not a goal.
  • Full Body Merging Logic: The synthetic response proposes a solution to merge responses. But particularly how to merge two response bodies might be handled by other proposals e.g. Declarative partial updates.
  • Offline Solution: While it utilizes the cache, it is primarily a performance optimization for connected navigations. It is not intended to replace full offline-first PWA architectures.

User research

There are many websites using Service Worker App Shell architecture. We can frame the synthetic response as a native support of App Shell.

Use cases

The Problem: The Network-to-Commit Gap Even with Static Routing API, standard navigation follows these steps.

  • Browser initiates a network request.
  • Idle Time: Browser waits for the server to respond (TTFB).
  • Browser receives the response.
  • Renderer Setup: Browser finds/creates a renderer process and starts the Commit phase.
  • Renderer begins loading and parsing.

The renderer is idle during step 2. For users on slow or high-latency networks, this gap is the primary source of perceived slowness.

Synthetic Response for navigations via the Static Routing API

self.addEventListener("install", e => {
  e.addRoutes({
    condition: { requestMode: "navigate" },
    source: {
      syntheticResponse: {
        cacheName: "static-resources",
        contentPath: "/app-shell.html",
        fallbackPath: /error-page.html”,
        timeout: 3000
      }
    }
  });
});

How this solution would solve the use cases

Key Performance Benefits:

  • Unblocking the Renderer: The renderer's life cycle (Find -> Commit -> Load) is moved much earlier in the timeline, often occurring before the server has even finished processing the request.
  • Decoupling from TTFB: Navigation commitment becomes a local operation (cache hit) rather than a network-bound operation.
  • Optimized Resource Discovery: By committing the shell early, the renderer can discover and start fetching static sub-resources (like site-wide CSS or fonts) defined in the of the shell while waiting for the primary body content.

Example: Cache for App Shell

This allows the browser to commit a full static UI shell while waiting for the body content.

self.addEventListener("install", e => {
  e.addRoutes({
    condition: { requestMode: "navigate" },
    source: {
      syntheticResponse: {
        cacheName: "static-resources",
        contentPath: "/app-shell.html", // Served immediately to trigger commit
        fallbackPath: /error-page.html”,
        timeout: 3000
      }
    }
  });
});

Example: Cache for HTTP Headers only

The simplest optimization: commit the renderer with just the cached headers. This allows the renderer to begin pre-initializing (e.g., preparing for the specific Content-Type) while the entire body comes from the network.

self.addEventListener("install", e => {
  e.addRoutes({
    condition: { requestMode: "navigate" },
    source: {
      syntheticResponse: {
        cacheName: "v1",
        httpHeaderPath: "/_header" // Minimal headers to unblock commit
      }
    }
  });
});

Detailed design discussion

  • Body Merging Strategy: Defining exactly where the network body starts and the cached shell ends. Declarative partial updates proposal might be a solution.
  • CSP Nonce Consistency: Handling Content Security Policy nonces that are typically unique per-request but are now partially served from a static cache. Using tag is one workaround, but it may be better to provide a way to inform browser generated nonce strings for CSP to servers, and encourage servers to use them.
  • Server Signaling: Providing a way for the server to know it only needs to send the "body" part (e.g., via a specialized request header).

Security and Privacy Considerations

The synthetic response has the same level of capability that the current Service Worker and Service Worker Static Routing API can do. Please refer the Security and Privacy section of the Service Worker Static Routing API proposal.

Stakeholder Feedback / Opposition

This proposal was presented at Web Applications WG TPAC 2025. There were no clear objections. More detailed design and proposal were requested to evaluate that this is really the case that existing Service Worker APIs can't achieve.

References & acknowledgements

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors