feat(FR-2521): add Suspense skeleton fallback to lazy-loaded pages#6596
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Coverage report for
|
St.❔ |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🔴 | Statements | 8.87% | 1735/19570 |
| 🔴 | Branches | 8.04% | 1097/13651 |
| 🔴 | Functions | 5.31% | 283/5328 |
| 🔴 | Lines | 8.56% | 1627/19009 |
Test suite run success
847 tests passing in 38 suites.
Report generated by 🧪jest coverage report action from 7b40b51
f05d8d2 to
59ae223
Compare
59ae223 to
eb3196f
Compare
Merge activity
|
…6596) Resolves #6595(FR-2521) ## Summary - Wrap all 20 lazy-loaded pages in `routes.tsx` with `<Suspense fallback={<Skeleton active />}>` that were missing loading indicators - Users now see an in-place skeleton instead of a blank screen during code-split chunk loading - Consistent with the pattern already used by DashboardPage, ComputeSessionListPage, etc. **Main layout pages (15)**: StartPage, MyEnvironmentPage, AgentSummaryPage, AdminSessionPage, EnvironmentPage, ResourcesPage, ResourcePolicyPage, ConfigurationsPage, MaintenancePage, DiagnosticsPage, BrandingPage, StorageHostSettingPage, Information, UserSettingsPage, UserCredentialsPage **Root-level pages (5)**: InteractiveLoginPage, EmailVerificationPage, ChangePasswordPage, EduAppLauncherPage (×2 routes) ## Verification ``` === ALL PASS === ``` ## Test plan - [ ] Navigate to each affected page and verify skeleton appears during lazy load - [ ] Verify no regressions on pages that already had Suspense boundaries - [ ] `verify.sh` passes (Relay, Lint, Format, TypeScript) 🤖 Generated with [Claude Code](https://claude.ai/code)
eb3196f to
7b40b51
Compare
There was a problem hiding this comment.
Pull request overview
Adds consistent in-place loading indicators for code-split route components by wrapping previously-unwrapped lazy-loaded pages in routes.tsx with React.Suspense using an Ant Design <Skeleton active /> fallback, reducing “blank screen” time on first navigation.
Changes:
- Wrapped multiple
mainLayoutChildRouteslazy pages with<Suspense fallback={<Skeleton active />}>. - Wrapped several root-level lazy routes (
/interactive-login,/verify-email,/change-password, launcher routes) with the same skeleton fallback. - Simplified the existing
/model-storeSuspense fallback to a plain<Skeleton active />.
| path: '/start', | ||
| element: <StartPage />, | ||
| element: ( | ||
| <Suspense fallback={<Skeleton active />}> | ||
| <StartPage /> | ||
| </Suspense> |
There was a problem hiding this comment.
The new route entries repeat the same <Suspense fallback={<Skeleton active />}>…</Suspense> wrapper many times. Consider extracting a small helper (e.g., a SuspenseSkeleton component or withSkeleton(element) function) so future fallback/style changes are centralized and route definitions stay compact.
| path: '/model-store', | ||
| handle: { labelKey: 'data.ModelStore' }, | ||
| Component: () => { | ||
| const baiClient = useSuspendedBackendaiClient(); | ||
| return ( | ||
| <Suspense | ||
| fallback={ | ||
| <BAIFlex direction="column" style={{ maxWidth: 700 }}> | ||
| <Skeleton active /> | ||
| </BAIFlex> | ||
| } | ||
| > | ||
| <Suspense fallback={<Skeleton active />}> | ||
| {baiClient?.supports('model-card-v2') ? ( | ||
| <ModelStoreListPageV2 /> |
There was a problem hiding this comment.
This hunk also changes the existing /model-store Suspense fallback from a constrained layout (used in several other fallbacks in this file) to a plain <Skeleton />. If the width constraint was intentional to match the page’s content/container, consider keeping the same constrained wrapper here or standardizing via a shared fallback component.

Resolves #6595(FR-2521)
Summary
routes.tsxwith<Suspense fallback={<Skeleton active />}>that were missing loading indicatorsMain layout pages (15): StartPage, MyEnvironmentPage, AgentSummaryPage, AdminSessionPage, EnvironmentPage, ResourcesPage, ResourcePolicyPage, ConfigurationsPage, MaintenancePage, DiagnosticsPage, BrandingPage, StorageHostSettingPage, Information, UserSettingsPage, UserCredentialsPage
Root-level pages (5): InteractiveLoginPage, EmailVerificationPage, ChangePasswordPage, EduAppLauncherPage (×2 routes)
Verification
Test plan
verify.shpasses (Relay, Lint, Format, TypeScript)🤖 Generated with Claude Code