Skip to content

Performance audit + defer search index warmup from app bootstrap#660

Merged
saint2706 merged 3 commits intomainfrom
perform-a-performance-audit
Mar 10, 2026
Merged

Performance audit + defer search index warmup from app bootstrap#660
saint2706 merged 3 commits intomainfrom
perform-a-performance-audit

Conversation

@saint2706
Copy link
Owner

Motivation

  • Run a focused performance audit (Lighthouse) against key app routes to identify main-thread and payload bottlenecks.
  • Reduce unnecessary startup work that contributes to high Total Blocking Time (TBT) and slow initial paints.

Description

  • Add a performance report at docs/performance-audit.md documenting Lighthouse results, findings, and rerun steps.
  • Pin @lhci/cli in devDependencies to provide an in-repo Lighthouse CI tooling path.
  • Remove eager search index preloading from application bootstrap by deleting preloadSearchIndex() in src/main.tsx.
  • Kick off background search indexing only when the Search page mounts by calling startBackgroundIndexing() in src/pages/SearchResults.tsx.

Testing

  • Ran dependency install with npm ci which completed successfully.
  • Built the production bundle with npm run build which completed successfully.
  • Ran type checking via npm run typecheck (tsc -b) which succeeded.
  • Installed Playwright/Chromium and supporting deps, then executed lhci collect (via CHROME_PATH=... npx lhci collect) which produced Lighthouse reports for the primary routes and saved results used in the audit document.

Codex Task

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4993d7ef27

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +65 to +67
useEffect(() => {
startBackgroundIndexing()
}, [])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Start index warmup before rendering prefilled search queries

When users land on /search?q=... (either direct URL or navigation with a query param), results is computed during the first render before this effect runs, so search() starts indexing but returns no engine yet and the page renders zero results. Because this component does not subscribe to index-status changes, it does not re-run the search when indexing later completes, so users can be stuck seeing "No lessons matched" until they edit the query. This regression appears after moving warmup out of app bootstrap and into a post-render effect.

Useful? React with 👍 / 👎.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a06166f355

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

src/App.tsx Outdated
Comment on lines +61 to +65
const idleId = (
window as Window & {
requestIdleCallback: (callback: () => void, options?: { timeout: number }) => number
}
).requestIdleCallback(hydrateStores, { timeout: 1500 })

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Hydrate persisted stores before deferring to idle

Scheduling store hydration via requestIdleCallback(..., { timeout: 1500 }) leaves skipHydration: true stores (quiz/gamification) in default state during startup, and mutating actions in that window can overwrite previously persisted data before rehydrate runs. For example, lesson completion calls useGamificationStore.getState().awardLessonCompletion(...), which persists immediately; with delayed hydration this can clobber existing XP/achievement history in localStorage on fast interactions. Hydration should run eagerly before user actions, or writes should be gated until hasHydrated is true.

Useful? React with 👍 / 👎.

@saint2706 saint2706 merged commit d3e7f18 into main Mar 10, 2026
6 of 7 checks passed
@saint2706 saint2706 deleted the perform-a-performance-audit branch March 10, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant