Skip to content

Improve resource list performance: virtual scrolling + lightweight counts - #277

Merged
nadaverell merged 2 commits into
mainfrom
feature/resource-list-perf
Mar 6, 2026
Merged

nadaverell merged 2 commits into
mainfrom
feature/resource-list-perf

Conversation

@nadaverell

Copy link
Copy Markdown
Contributor

Summary

Phase 1 of the large-cluster performance plan (follow-up to #273).

  • Sidebar counts: The Resources page was firing ~233 parallel GET /api/resources/{kind} calls (608MB total) just to populate sidebar count badges. Now uses a single GET /api/resource-counts call (~2KB). Full resource data is only fetched for the currently selected kind.

  • Table virtualization: Resource lists with thousands of items (e.g., 3,500 ReplicaSets → 35,000 DOM nodes) caused multi-second renders and scroll jank. Replaced .map() rendering with TableVirtuoso from react-virtuoso (already in deps). Only visible rows + buffer are rendered (~500 DOM nodes). Layout switches from CSS grid to table-layout: fixed with <colgroup>. Keyboard navigation and deep-link scrolling use scrollToIndex().

New props on ResourcesView (resourceCounts, resourceForbidden, selectedKindQuery, onSelectedKindChange) are additive — the legacy resourceQueries array still works for backward compatibility.

Test plan

  • Open Resources page — sidebar counts load quickly, no waterfall of 233 requests in DevTools Network tab
  • Click different resource kinds — table data loads for selected kind only
  • With 1,000+ resources of one kind: smooth 60fps scrolling, no jank
  • Column resize, sort, filter, search all work
  • Keyboard navigation (j/k/Enter) scrolls to highlighted row
  • Deep-linking (/resources/pods?resource=...) scrolls to correct row
  • Small clusters (< 50 resources per kind) — no UX degradation

…unts

Two frontend performance improvements for large clusters:

1. Sidebar counts: Replace 233 parallel GET /api/resources/{kind} queries
   (608MB total) with a single GET /api/resource-counts call (~2KB).
   Full resource data is now fetched only for the currently selected kind.

2. Table virtualization: Replace .map() rendering with TableVirtuoso
   (react-virtuoso). Only visible rows + buffer are in the DOM (~500 nodes
   instead of ~35,000 for 3,500 resources). Switches from CSS grid layout
   to table-layout:fixed with colgroup for column widths. Keyboard
   navigation and deep-link scrolling use scrollToIndex().
@nadaverell
nadaverell requested a review from hisco as a code owner March 6, 2026 13:55
…ppers

- Throw ApiError on all non-OK responses instead of silent return []
- Fix forbiddenKinds guard to use useNewCountsMode only (omitempty compat)
- Remove unnecessary setSelectedKind wrapper and handleSelectedKindChange
@nadaverell
nadaverell merged commit ee8c660 into main Mar 6, 2026
6 checks passed
@nadaverell
nadaverell deleted the feature/resource-list-perf branch March 6, 2026 15:22
jessegoodier pushed a commit to jessegoodier/radar that referenced this pull request Mar 6, 2026
…unts (skyhook-io#277)

* Improve resource list performance: virtual scrolling + lightweight counts

Two frontend performance improvements for large clusters:

1. Sidebar counts: Replace 233 parallel GET /api/resources/{kind} queries
   (608MB total) with a single GET /api/resource-counts call (~2KB).
   Full resource data is now fetched only for the currently selected kind.

2. Table virtualization: Replace .map() rendering with TableVirtuoso
   (react-virtuoso). Only visible rows + buffer are in the DOM (~500 nodes
   instead of ~35,000 for 3,500 resources). Switches from CSS grid layout
   to table-layout:fixed with colgroup for column widths. Keyboard
   navigation and deep-link scrolling use scrollToIndex().

* Fix review findings: error handling, forbidden fallback, simplify wrappers

- Throw ApiError on all non-OK responses instead of silent return []
- Fix forbiddenKinds guard to use useNewCountsMode only (omitempty compat)
- Remove unnecessary setSelectedKind wrapper and handleSelectedKindChange
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