Performance audit + defer search index warmup from app bootstrap#660
Performance audit + defer search index warmup from app bootstrap#660
Conversation
There was a problem hiding this comment.
💡 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".
| useEffect(() => { | ||
| startBackgroundIndexing() | ||
| }, []) |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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
| const idleId = ( | ||
| window as Window & { | ||
| requestIdleCallback: (callback: () => void, options?: { timeout: number }) => number | ||
| } | ||
| ).requestIdleCallback(hydrateStores, { timeout: 1500 }) |
There was a problem hiding this comment.
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 👍 / 👎.
Motivation
Description
docs/performance-audit.mddocumenting Lighthouse results, findings, and rerun steps.@lhci/cliindevDependenciesto provide an in-repo Lighthouse CI tooling path.preloadSearchIndex()insrc/main.tsx.startBackgroundIndexing()insrc/pages/SearchResults.tsx.Testing
npm ciwhich completed successfully.npm run buildwhich completed successfully.npm run typecheck(tsc -b) which succeeded.lhci collect(viaCHROME_PATH=... npx lhci collect) which produced Lighthouse reports for the primary routes and saved results used in the audit document.Codex Task