Skip to content

Render the study interface while participant startup resolves #1320

Description

@JackWilb

Summary

Participant startup currently keeps the study interface behind a synchronous loading barrier while authentication, participant restoration, completion detection, assignment, and other storage work resolve. HAR profiling from #1176 showed that these provider requests can leave participants looking at a loading state for several seconds even when the study configuration is already available.

Render the study interface and begin loading its assets as soon as the config is parsed, while retaining a consistent, fully blocking spinner until participant state is authoritative.

This follows #1176 and PR #1311. It is complementary to #1319, which moves sequence-artifact publication off the interaction-critical path.

UX direction

Keep the existing startup-spinner convention rather than introducing a new modal style:

  • Mount the normal study layout, including the main area and sidebar, behind the loading state.
  • Render the spinner in the main study area or as an overlay above the interface.
  • Apply a scrim/input barrier across the entire study interface so the sidebar and all other controls remain non-interactable.
  • Avoid layout shifts when initialization completes and the spinner disappears.

The goal is to start React rendering and asset loading earlier, not to let participants interact with provisional state.

Required startup barrier

Do not unlock interaction until all state that can change the participant's route or sequence is authoritative:

  • Authentication and App Check are ready.
  • Existing participant data has been restored or confirmed absent.
  • Completion status is resolved.
  • A new participant's race-safe assignment has been committed.
  • The participant's correct config version and assigned sequence are available.

Never optimistically display an interactive first task and later replace it. Existing participants may need to resume mid-study or be routed to a completed state.

Requirements

  • Introduce an explicit, idempotent startup state machine rather than coupling interface mounting to one aggregate loading boolean.
  • Mount routes and the study layout as soon as the parsed config is available.
  • Begin component, stylesheet, markdown, image, and other study-resource loading while the blocking spinner is visible.
  • Prevent pointer, keyboard, and programmatic navigation through the study until startup is ready.
  • Ensure the loading treatment covers the sidebar as well as the main content.
  • Preserve current behavior for completed participants, resumed participants, URL conditions, stages, development mode, and disabled data collection.
  • Define recoverable error and retry states without duplicating participant creation or sequence assignment.
  • Ensure React StrictMode/effect re-execution cannot start duplicate initialization operations.
  • Keep accessibility state accurate using an appropriate busy status and focus behavior.

Acceptance criteria

  • The normal study layout mounts before remote participant initialization finishes.
  • Study assets begin loading while the startup spinner is visible.
  • The spinner is presented consistently in the study interface or above it, with the entire interface—including the sidebar—non-interactable.
  • No response can be entered or persisted before completion, resume, and assignment state is authoritative.
  • Completed and resumed participants never briefly receive an interactive incorrect task.
  • Initialization executes at most once per study/participant startup despite rerenders and StrictMode behavior.
  • Recoverable provider failures provide retry behavior without duplicate participants or assignments.
  • UI tests cover fresh, resumed, completed, failure/retry, and slow-provider startup states.
  • Browser profiling records both first render and time-to-interactive for a large study such as library-calvi.
  • yarn unittest --run, yarn typecheck, yarn lint, and yarn build pass.

Out of scope

Activity

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

Metadata

Metadata

Labels

SpecifiedIssue has enough detail to implementbugSomething isn't working

Type

No type

Projects

  • Status
    Next Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions