Skip to content

feat(dashboard): add panel-level Suspense boundaries for independent loading (#94)#149

Open
Sujini-kudupudi wants to merge 2 commits into
Coder-s-OG-s:mainfrom
Sujini-kudupudi:feature/dashboard-suspense
Open

feat(dashboard): add panel-level Suspense boundaries for independent loading (#94)#149
Sujini-kudupudi wants to merge 2 commits into
Coder-s-OG-s:mainfrom
Sujini-kudupudi:feature/dashboard-suspense

Conversation

@Sujini-kudupudi
Copy link
Copy Markdown

Summary

This PR implements panel-level <Suspense> boundaries across the contributor dashboard. Previously, the dashboard executed 5+ parallel queries inside a single, page-level Server Component. Because Next.js Server Components block rendering until all awaited promises resolve, a slow fetch (such as recommendations, leaderboard query, or Redis streak check) would delay the entire page load, leaving users with a blank screen.

By extracting each panel into its own async Server Component and wrapping them in independent <Suspense> boundaries, the page shell and header render instantly, and each dashboard panel renders dynamically as soon as its own data is ready.

Type of Change

  • Bug fix
  • New feature
  • UI / UX improvement
  • Refactor
  • Documentation
  • Other (Performance & Data Streaming Improvement)

Related Issue

Closes #94

What was changed?

  1. Stats Row Component (stats-row.tsx): Created a new async server component to handle Redis caches, level progress, and mentor points queries independently. Defined the custom StatsSkeleton fallback.
  2. Active Issues Component (active-issues.tsx): Created a new async server component to fetch recommendations asynchronously. Defined the custom RecsSkeleton fallback (showing 2 animated issue card loaders).
  3. GitHub PRs Wrapper Component (github-prs-wrapper.tsx): Created a new async server component to fetch contributor PRs and matching claimed recommendation URLs. Defined the PrsSkeleton fallback.
  4. Leaderboard Snapshot Component (leaderboard-snapshot.tsx): Created a new async server component to load global contributor rankings, incorporating the updated empty-board message from upstream. Defined the LeaderboardSkeleton fallback.
  5. Mentees Section Component (mentees-section.tsx): Created a new async server component to fetch active help requests assigned to the mentor. Defined the MenteesSkeleton fallback.
  6. Dashboard Page Shell (page.tsx): Simplified DashboardPage to perform fast session checks and the basic profile lookup. All sub-panels are now nested within individual <Suspense> containers with beautiful, theme-matching skeleton fallbacks.

Screenshots

N/A (UI layouts and colors are fully preserved, now enhanced with beautiful animated pulse skeleton loaders for independent loading).

Checklist

  • My code follows the project structure and conventions
  • I tested this locally (npm run dev)
  • No hardcoded secrets or credentials
  • I have updated documentation if needed

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 17, 2026

@Sujini-kudupudi is attempting to deploy a commit to the codersogs-3057's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Ayush-Patel-56
Copy link
Copy Markdown
Collaborator

Please see this #67 (comment)

Copy link
Copy Markdown
Collaborator

@Siddhartha-singh01 Siddhartha-singh01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Suspense refactor itself is exactly the right pattern for #94 @Sujini-kudupudi
extracting each slow panel into its own Server Component with a <Suspense> boundary
and a skeleton fallback is the textbook App Router approach, and the page shell going
from ~458 to 117 lines is a real win. The skeleton fallbacks per panel will make the
perceived performance much better than the previous "wait for the slowest query"
behavior.

Two things to sort before merge:

  1. Scope bleed-in from PR #124. Your commit list includes 4 commits from #124 (the
    recommendations server-actions tests), and recommendations.test.ts (+391 lines)
    is in this PR's diff. Cleanest path: wait for #124 to merge first, then rebase this
    PR on main the test commits will drop out of this diff automatically, leaving
    only the dashboard refactor. Otherwise the PR is doing two unrelated things and
    #124 becomes redundant.

  2. profile: any in stats-row.tsx. Ironically, one of the commits in this PR
    (27fd784) is the any → unknown cleanup. The new StatsRow accepts profile: any
    please give it a proper type matching the fields fetched in page.tsx
    (github_handle, xp, level, github_total_merges, github_streak, github_stats_synced_at).

Minor: a screenshot or short clip of the staggered panel loading would help reviewers
verify the UX without running locally the description says "N/A" but this is
exactly the kind of change where visual confirmation matters.

I checked page.tsx carefully for any merge corruption (lessons learned from #151
😅) and it parses cleanly structure is intact.

Once #124 lands and you've rebased + fixed the profile: any, and CI goes green,
this is ready to merge. Solid refactor overall

Thanks!

@Ayush-Patel-56
Copy link
Copy Markdown
Collaborator

can you please check the failing tests ?

@Sujini-kudupudi
Copy link
Copy Markdown
Author

can you please check the failing tests ?
Sure, give me a few minutes. I’m working on them.

@Sujini-kudupudi Sujini-kudupudi force-pushed the feature/dashboard-suspense branch from 9469d2e to c009443 Compare May 22, 2026 18:28
@Sujini-kudupudi
Copy link
Copy Markdown
Author

Thanks for the review Siddhartha! I have completely rebased the branch onto main to drop the extra commits, fixed the any typing to match the DB fields, and resolved the CI formatting issues. All checks are passing now! Here is a quick video showing the new staggered Suspense loading in action as requested

screen-recording-2026-05-23-003936_kfEn2iEY.mp4

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.

Add Suspense boundaries to dashboard so panels load independently

3 participants