feat: Paginate and memoize the admin QuestTable rendering - #2164
Merged
RUKAYAT-CODER merged 4 commits intoAug 20, 2026
Conversation
Contributor
|
Well done on the task done so far! |
- Format all files with prettier to pass format:check - Add @contracts and @stellar/stellar-sdk aliases to vitest.config so useClaim.test resolves contract bindings - Import React in useReputation.test to fix 'React is not defined' - Guard nullable useParams/useSearchParams/usePathname results so next build passes with the pages-router compat navigation types - Ignore generated benchmark output (scripts/benchmarks/results/*.latest.json)
Contributor
Author
|
@RUKAYAT-CODER...i'm so sorry for the delay...please review |
Contributor
|
Thank you for contributing to the project. |
4 tasks
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.
Close #2151
Title
perf(admin): paginate and memoize quest table rows
Summary
The admin quest table rendered the full quest list at once and rebuilt the row
action handlers for every row on every render, making the admin surface slow and
janky as the quest count grows.
This PR:
QuestTable(10 / 25 / 50 / 100 rows perpage, default 10) with Previous / Next controls, a page indicator, and a
"Showing X–Y of Z" range readout. The page resets to 1 whenever the
questsprop changes identity (filter, sort, or refetch), so users never land on an
empty page.
React.memo'dQuestTableRowand wrapsQuestRowActionsinReact.memo, so a single checkbox toggle or sortchange no longer re-renders every row.
onToggleSelect,onEdit,onDelete) withuseCallbackso the memoized rows are not invalidated byincidental re-renders of the table.
QuestTablePropsis unchanged —QuestManagerand the admin page required nomodifications, and existing functionality is preserved.
Motivation
Rendering thousands of
<tr>elements and rebuilding every row's handlers oneach state change produced:
quest count).
re-render (selection update cost scales with quest count).
Changes
components/admin/QuestTable.tsxpage,pageSize) withPAGE_SIZE_OPTIONSandDEFAULT_PAGE_SIZE.currentPageclamping and auseEffectthat resets to page 1 when thequestsprop changes.visibleQuestsuseMemoslice.QuestTableRow(checkbox, title/category, status badge,reward, participants, deadline, actions).
onToggleSelect,onEdit, andonDeleteinuseCallback."Page X of Y" indicator) with
data-testids for testing.components/admin/QuestRowActions.tsxReact.memoto prevent needless re-renders.Benchmark harness (new)
scripts/benchmarks/quest-table.render.bench.tsx— measures mount time andselection-update time for datasets of 200 and 1000 quests (best-of-3,
jsdom), writing JSON results.
vitest.benchmark.config.ts— dedicated Vitest config so benchmarks neverrun as part of the normal
npm testsuite.package.json— newbenchmark/benchmark:quest-tablescripts.scripts/benchmarks/results/quest-table.baseline.json(before) and
quest-table.optimized.json(after).Tests (new)
components/admin/__tests__/QuestTable.pagination.test.tsx— page-size-boundrendering, Previous / Next navigation, boundary disabling, page reset on new
quests, page-size change, and absence of the footer for loading / emptystates.
components/admin/__tests__/QuestTable.memo.test.tsx— verifies thatchanging the selection re-renders only the affected row, and that changing
the callback identities re-renders all rows (guards against over-memoizing).
Docs
docs/ADMIN_QUEST_TABLE_PERFORMANCE.md— full write-up with methodology,before/after numbers, and how to re-run the benchmark.
CHANGELOG.md— added entry under Unreleased with the before/after table.Before/After Performance
Benchmark: best-of-3 render timings in jsdom (mount = initial render of N
quests; update = re-render after a single-row selection change).
Key property: cost is now flat — mounting 1000 quests is no more expensive
than mounting 200, because only one page of rows is rendered and unchanged rows
are never re-rendered.
Re-run with:
cd FrontEnd/my-app npm run benchmark:quest-tableTesting
npm test(frontend): 809 passed / 3 failed — the 3 failures(
app/layout.test.tsx,lib/hooks/useClaim.test.ts,lib/hooks/useReputation.test.tsx)are pre-existing on the base branch and unrelated to this change (verified by
running them against a clean checkout).
QuestTable.pagination.test.tsx(7) andQuestTable.memo.test.tsx(2) all pass; the full admin component suite (60tests) passes.
npm run lint— clean on all touched files.npm run typecheck— no new errors (the 7 remaining errors are pre-existingon the base branch).
prettier --check— clean on all touched files.npm test(repo tooling suite) — passes.Acceptance Criteria
the 3 failures exist on the base branch too)
Notes / Follow-ups
sorted list in
useQuestFilters, so it needs no server changes.swapped for the existing
VirtualizedListwindowing component, butpagination is simpler for a tabular admin surface and matches the stated
implementation plan.