Skip to content

SW clients.claim() causes an unconditional reload on a brand-new browser context's first page load #585

Description

@qnbs

Summary

public/sw.js calls self.clients.claim() on activate, and register-sw.ts's flushLatestStateThenReload() unconditionally calls window.location.reload() whenever navigator.serviceWorker.controllerchange fires while the page is visible.

clients.claim() claims already-open clients immediately, not just future navigations. On a completely fresh browser context (no prior service worker), the very first page load's register() → install → activate → clients.claim() sequence therefore fires controllerchange on that same first-ever page, not only on a version update for a returning visitor. The result: every first-time visitor, and every fresh E2E browser context, undergoes one automatic, unprompted reload shortly after the initial page load — a "double boot" that appears to be an accepted-but-undocumented side effect of the "always fresh, no waiting" SW update strategy, not something anyone deliberately decided should also apply to first-ever installs.

Why this matters

Surfaced during PR #583's investigation of #532 (WelcomePortal startup/navigation E2E nondeterminism). This reload is asynchronous and can land at an arbitrary point during page interaction, which is a plausible (not yet proven) contributor to some historical #532-class flakiness, independent of the addInitScript-ordering and factory-reset-connection races #532/#583 already fixed.

Scope for a fix

Two independent directions, not mutually exclusive:

  1. Production behavior: decide whether a first-ever install should reload at all. If the intent was only to ensure a returning visitor picks up a new version promptly, clients.claim()/the reload logic could distinguish first-install from update (e.g. skip the reload path when there was no prior controller before this activation).
  2. E2E robustness: independent of whether (1) changes, tests/e2e/helpers.ts's startup helpers (waitForSpaReady, resolveStartupState, ensureWelcomePortalEntry) should be verified robust to an unprompted navigation landing mid-action, not just mid-idle.

Non-goals

Not a #532 regression by itself — #532's fixed root causes (in #583) are independent of this. This should not be used to reopen #532; it's tracked here so it isn't lost, and can be referenced from #532 for context.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions