perf: memoize + virtualize order list, batch storage writes - #16
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Side-panel list felt laggy once saved orders piled up. Traced it to a stack of React anti-patterns plus O(N)
chrome.storageroundtrips on batch delete, and one latent bug that blanks the whole panel when OAuth env is missing.Performance
OrderCardnow wrapped inReact.memo; every handler passed fromOrderTableisuseCallback-stable, so search keystrokes / selection / status change no longer re-render every card in the list.useDeferredValue— input stays responsive, filter/sort runs at low priority.@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.updateManybatches the N sequential read-modify-write cycles inuseDeleteOrdersinto one pass.selectedIdscleanup effect now depends onordersinstead ofdisplayOrdersso it doesn't run on every keystroke.AuthContexttoken effect depends onaccess_tokeninstead of the wholeuserobject — token refresh no longer cascades.Fix
oauth.tsused to callnew 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 tosignIn/signOutandauthorizationServeris built defensively, so local-only flows boot without OAuth configured.Dev
apps/extension/scripts/seed-orders.js— paste into side-panel DevTools Console forseed(n)/clearOrders()to stress-test the list.Test plan
bun run typecheck(extension)bun run test— 57 passed.env; seeded 500 orders and confirmed smooth scroll, DOM shows ~10 cards during scroll, search input stays responsive while filtering.