Skip to content

perf: memoize + virtualize order list, batch storage writes - #16

Merged
spinsirr merged 4 commits into
mainfrom
spinsirr/adoring-moser-27179c
Apr 23, 2026
Merged

perf: memoize + virtualize order list, batch storage writes#16
spinsirr merged 4 commits into
mainfrom
spinsirr/adoring-moser-27179c

Conversation

@spinsirr

Copy link
Copy Markdown
Owner

Summary

Side-panel list felt laggy once saved orders piled up. Traced it to a stack of React anti-patterns plus O(N) chrome.storage roundtrips on batch delete, and one latent bug that blanks the whole panel when OAuth env is missing.

Performance

  • OrderCard now wrapped in React.memo; every handler passed from OrderTable is useCallback-stable, so search keystrokes / selection / status change no longer re-render every card in the list.
  • Search uses useDeferredValue — input stays responsive, filter/sort runs at low priority.
  • List virtualized with @tanstack/react-virtual — DOM holds only visible cards + small overscan regardless of total count (tested with 500 seeded orders, DOM stays ~10 cards during scroll).
  • LocalStorageRepository.updateMany batches the N sequential read-modify-write cycles in useDeleteOrders into one pass.
  • selectedIds cleanup effect now depends on orders instead of displayOrders so it doesn't run on every keystroke.
  • AuthContext token effect depends on access_token instead of the whole user object — token refresh no longer cascades.

Fix

  • oauth.ts used to call new URL(VITE_COGNITO_AUTHORITY) at module import. When the env var was undefined the whole side panel went blank with only a console error. Validation is now deferred to signIn / signOut and authorizationServer is built defensively, so local-only flows boot without OAuth configured.

Dev

  • Added apps/extension/scripts/seed-orders.js — paste into side-panel DevTools Console for seed(n) / clearOrders() to stress-test the list.

Test plan

  • bun run typecheck (extension)
  • bun run test — 57 passed
  • Manual: side panel renders without .env; seeded 500 orders and confirmed smooth scroll, DOM shows ~10 cards during scroll, search input stays responsive while filtering.

Previously new URL(cognitoAuthority) ran at module import time. When
VITE_COGNITO_AUTHORITY was undefined the side panel crashed before any
component rendered, producing a blank white panel with only a console error.

Now authorizationServer is built defensively and an assertOAuthConfigured
helper throws a clear message only when signIn/signOut are actually invoked.
The app boots and local-only flows work without any OAuth config.
Main panel was laggy once the saved order list grew. Several compounding
React anti-patterns plus O(N) storage roundtrips on batch delete.

- Wrap OrderCard in React.memo and stabilize every callback passed to it
  with useCallback so selection, status changes, and search keystrokes no
  longer re-render every card in the list.
- Use useDeferredValue for the search query so the input stays responsive
  while filter/sort runs at low priority.
- Virtualize the order list with @tanstack/react-virtual. DOM now holds
  only the visible cards plus a small overscan regardless of list size.
- Add LocalStorageRepository.updateMany and use it in useDeleteOrders to
  collapse N sequential read-modify-write cycles into a single pass.
- Prune selectedIds only when the underlying orders set changes, not on
  every search keystroke.
- Narrow the AuthContext token effect to depend on access_token instead
  of the full user object so token refresh does not cascade re-renders.
Paste into side panel DevTools Console to populate chrome.storage.local
with N fake orders via seed(n), or wipe via clearOrders(). Useful when
verifying virtualization and memoization under a realistic load.
@spinsirr
spinsirr merged commit e50a70f into main Apr 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant