Skip to content

Lots of studies load really slowly #1176

Description

@mcnuttandrew

There are a number of studies where it takes a long time to load them. I know we've fixed slow loading bugs before, but this is omnibus issue for slow loading


Specification

Added after specification review.

Summary

Reduce normal participant startup time by removing repeated, serialized, and unbounded storage-provider operations. The implementation must improve both Firebase and Supabase while preserving LocalStorage behavior and all existing sequence-assignment semantics.

Decisions

  • Scope this issue to normal participant startup. Analysis/replay loading through the reserved participantId query parameter and general application-bundle optimization are separate concerns.
  • Normal startup must not perform collection-wide sequence-assignment scans.
  • Any assignment-level change must remain race-safe. An atomic counter, transaction, or equivalent bounded operation that prevents duplicate or incorrectly ordered assignments under concurrent participant starts is table stakes.
  • Preserve the existing persisted 1,000-sequence-array format in this issue, but download the array at most once per startup and reuse the in-memory value.
  • Support Firebase and Supabase. LocalStorage must continue to work as a regression baseline.
  • Existing studies and participant sessions must require no manual migration. Any new allocator metadata must initialize lazily and atomically while remaining compatible with existing assignments.
  • Preserve current Latin-square ordering, random ordering, URL conditions, stages, rejected-assignment reuse, and participant-resume behavior.
  • Use the locally available library-nasa-tlx study, represented by https://revisit.dev/study/library-nasa-tlx/SURHUmJIblo3Uk4xUUhNUHQ1VTRIQT09, as the representative before/after browser benchmark.
  • Profiling instrumentation may be added temporarily for the PR, but it does not need to ship in the application.

Acceptance Criteria

  • Firebase and Supabase normal participant startup perform no full sequence-assignment collection scan.
  • Assignment allocation uses a bounded, race-safe provider operation and remains correct under simultaneous participant starts.
  • Completion status uses a participant-specific assignment lookup rather than loading all assignments.
  • The sequence array is downloaded at most once per startup.
  • Modes and stage data are fetched at most once per startup.
  • Supabase database verification does not use select('*') and retrieves at most one lightweight row.
  • An unchanged active config does not require downloading the stored config merely to prove that it exists.
  • Existing assignment records, sequence arrays, rejected-assignment reuse, and participant sessions remain readable without manual migration.
  • Existing Latin-square, randomization, URL-condition, stage, rejection-reuse, and resume behavior is unchanged.
  • Storage-engine contract tests assert the permitted startup operation counts for Firebase, Supabase, and LocalStorage.
  • Concurrency tests cover simultaneous assignment, rejected-assignment claiming, and lazy allocator initialization.
  • Shell tests verify that completion detection no longer causes a collection scan.
  • The local library-nasa-tlx study is benchmarked before and after using at least five fresh-participant loads under the same browser, build, provider, and network conditions.
  • The representative benchmark has a median time-to-interactive no greater than 3 seconds and improves by at least 40% from the recorded baseline.
  • Temporary profiling code used for the PR is removed before merge.
  • yarn unittest --run, yarn typecheck, yarn lint, and yarn build pass.

Implementation Notes

The investigation found that local CPU work is not the primary bottleneck: bundled-study config parsing remained under 8 ms, 1,000-sequence generation under 74 ms, and Redux-store construction under 2 ms.

The current storage path has several scaling problems:

  • A fresh participant loads the entire sequence-assignment collection before assignment creation, after assignment creation, and again for completion status.
  • The generated sequence array is loaded in Shell and then loaded again inside _getSequence. Bundled arrays reach approximately 3.4 MiB, producing about 6.8 MiB of duplicate transfer.
  • Supabase _verifyStudyDatabase currently selects every column for every matching study row merely to verify database existence.
  • Config, modes, and completion checks add redundant serialized reads to the critical path.

Implementation details may differ by provider, but the public storage-engine contract must expose bounded behavior and preserve concurrency correctness.

Testing Notes

  • Add focused unit and contract tests beside the storage and Shell code they exercise.
  • Assert operation counts, not only returned values, so future changes cannot silently reintroduce collection scans or duplicate sequence downloads.
  • Exercise fresh participants, locally cached resumes, remote resumes without a local cache, disabled data collection, existing allocator metadata, lazy allocator initialization, concurrent starts, URL conditions, stages, and rejected-assignment reuse.
  • Record the NASA-TLX benchmark setup and before/after results in the PR description so reviewers can reproduce the measurement.

Out of Scope

  • Analysis/replay startup and its audio, provenance, transcript, tag, and recording requests.
  • Redesigning the persisted sequence-array representation around deterministic seeds or assignment indexes.
  • Broad application bundle splitting or static asset optimization.
  • Changing study randomization or balancing semantics.
  • Adding a new dependency.
  • Production analytics or persistent participant-level performance telemetry.

Metadata

Metadata

Assignees

Labels

SpecifiedIssue has enough detail to implementbugSomething isn't working

Type

No type

Projects

Status
In progress

Relationships

None yet

Development

No branches or pull requests

Issue actions