perf(web): defer timezone indexing until picker opens #123

Merged
eleith merged 1 commits from perf/lazy-timezone-index into main 2026-11-03 16:36:03 +00:00

Summary

Build the timezone search index only when someone first opens the picker, instead of during server rendering and initial hydration. This defers the expensive Intl setup for a control most visitors never use.

Everything stays client-side: no API call, new dependency, timezone dataset, or configuration. Current-timezone labels and booking calculations still work without the search index.

Behavior

  • Open the dialog immediately with “Loading timezones…”. Search accepts typing and the dialog can be closed while initialization runs.
  • Yield before the first batch and between batches of eight timezones, rather than constructing the whole index in one uninterrupted task.
  • Share pending work and cache the completed result across reopening. Closing does not restart initialization.
  • Publish complete results without showing premature “No matches”; preserve existing search tokens, abbreviations, seasonal names, and offsets.
  • Keep the dialog height stable when loading finishes. Scroll the selected option into view without stealing focus.
  • Offer a focused retry path if initialization fails; clear failed cached work.

Readability

Opening and retrying use named handlers. The open lifecycle callback focuses the search field and starts loading, replacing the loading effect and untrack. The one remaining effect handles scrolling after results render. Descriptive names and raw immutable index state keep the data flow explicit and avoid deep-proxy overhead.

Validation

  • 1,169 web unit tests pass, including 16 timezone tests.
  • 23 Chromium browser checks pass, covering the timezone picker, absolute slot links, booking/rescheduling, duration controls, inline critical CSS, security headers, and hydration.
  • New browser scenarios cover mobile and desktop, zero indexing before opening, no indexing-related API calls, typing/closing/reopening during loading, cache reuse, preserved focus, timezone selection and cookie persistence, and failed initialization/retry.
  • Type checking, formatting, ESLint, and diff checks pass.
  • Independent code and readability reviews completed with no actionable findings after cleanup.
  • Includes a patch changeset.

This defers CPU work; it does not remove the index code from the initial JavaScript bundle. First-time picker users see a loading state. No new PageSpeed score improvement is claimed without a deployment measurement.

## Summary Build the timezone search index only when someone first opens the picker, instead of during server rendering and initial hydration. This defers the expensive `Intl` setup for a control most visitors never use. Everything stays client-side: **no API call, new dependency, timezone dataset, or configuration**. Current-timezone labels and booking calculations still work without the search index. ## Behavior - Open the dialog immediately with “Loading timezones…”. Search accepts typing and the dialog can be closed while initialization runs. - Yield before the first batch and between batches of eight timezones, rather than constructing the whole index in one uninterrupted task. - Share pending work and cache the completed result across reopening. Closing does not restart initialization. - Publish complete results without showing premature “No matches”; preserve existing search tokens, abbreviations, seasonal names, and offsets. - Keep the dialog height stable when loading finishes. Scroll the selected option into view without stealing focus. - Offer a focused retry path if initialization fails; clear failed cached work. ## Readability Opening and retrying use named handlers. The open lifecycle callback focuses the search field and starts loading, replacing the loading effect and `untrack`. The one remaining effect handles scrolling after results render. Descriptive names and raw immutable index state keep the data flow explicit and avoid deep-proxy overhead. ## Validation - **1,169 web unit tests pass**, including 16 timezone tests. - **23 Chromium browser checks pass**, covering the timezone picker, absolute slot links, booking/rescheduling, duration controls, inline critical CSS, security headers, and hydration. - New browser scenarios cover mobile and desktop, zero indexing before opening, no indexing-related API calls, typing/closing/reopening during loading, cache reuse, preserved focus, timezone selection and cookie persistence, and failed initialization/retry. - Type checking, formatting, ESLint, and diff checks pass. - Independent code and readability reviews completed with no actionable findings after cleanup. - Includes a patch changeset. This defers CPU work; it does not remove the index code from the initial JavaScript bundle. First-time picker users see a loading state. No new PageSpeed score improvement is claimed without a deployment measurement.
eleith-gitea-agent Bot added 1 commit 2026-11-03 16:33:15 +00:00
perf(web): defer timezone indexing until picker opens
ci/woodpecker/pr/web Pipeline was successful
ci/woodpecker/push/web Pipeline was successful
f159f360ca
eleith merged commit f159f360ca into main 2026-11-03 16:36:03 +00:00
eleith deleted branch perf/lazy-timezone-index 2026-11-03 16:36:03 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: eleith/when#123