feat: Implement Route-Level Code Splitting (Lazy Loading) for Performance Optimization - #141
Open
sarv-tech wants to merge 3 commits into
Open
feat: Implement Route-Level Code Splitting (Lazy Loading) for Performance Optimization#141sarv-tech wants to merge 3 commits into
sarv-tech wants to merge 3 commits into
Conversation
This implements lazy loading for all page-level routes and introduces an accessible GlobalLoader for the Suspense boundary. It also fixes pre-existing empty interfaces and unused ts-expect-error comments without relaxing the global eslint configuration.
|
Someone is attempting to deploy a commit to the Sufal Basak's projects Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
This PR introduces route-level code splitting in the React app by converting page-level route components in src/App.tsx to React.lazy() dynamic imports, wrapped in a global Suspense boundary with an accessible loading fallback. It also includes small UI-layer type cleanups and minor lint-related adjustments.
Changes:
- Refactored
src/App.tsxto lazy-load page routes and render them inside<Suspense fallback={<GlobalLoader />}>(withinDebugErrorBoundary). - Added a new
src/components/ui/GlobalLoader.tsxcomponent to serve as the Suspense fallback UI. - Cleaned up a few UI typings (empty interfaces → type aliases) and removed/adjusted TypeScript ignore usage.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tailwind.config.ts | Adds an ESLint suppression for the Tailwind plugin require() usage. |
| src/components/ui/textarea.tsx | Replaces an empty props interface with a type alias. |
| src/components/ui/GlobalLoader.tsx | Introduces the global Suspense fallback loader UI. |
| src/components/ui/command.tsx | Replaces an empty props interface with a type alias. |
| src/components/typing/TypingTest.tsx | Removes TS-ignore comments; minor behavior/documentation cleanup needed. |
| src/App.tsx | Implements route-level lazy loading with Suspense + error boundary. |
| package-lock.json | Lockfile updates from dependency resolution/install. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Author
|
Hi @SufalBasak, I've Created a PR kindly review, approve & Add labels |
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.
Description
This PR implements route-level code splitting using
React.lazy()and<Suspense>to significantly optimize the application's initial load performance.Previously, all major page components were imported synchronously in
App.tsx, which forced Vite to bundle the entire application into a single, massive JavaScript chunk. This resulted in a bloated initial payload, negatively impacting Time to Interactive (TTI) and Largest Contentful Paint (LCP) metrics.By strategically lazily loading all 18+ page-level routes, we have decoupled the heavy views (e.g., Voice Practice, Verbal Game, Practice Hub) from the main bundle. The browser now only fetches the specific JavaScript chunk required for the active route, downloading additional chunks dynamically as the user navigates.
Key Changes
App.tsxto replace all static page imports withReact.lazy(() => import('...')).<Routes>layer inside a<Suspense>component to gracefully handle the asynchronous chunk loading.<GlobalLoader />fallback component (src/components/ui/GlobalLoader.tsx). It featuresaria-live="polite"androle="status"properties, ensuring screen readers announce the loading transition for visually impaired users.<Suspense>boundary directly inside the pre-existing<DebugErrorBoundary>. If a network interruption causes aChunkLoadErrorduring navigation, the application gracefully degrades to a clean fallback UI rather than crashing.@ts-expect-errorcomments in the UI layer without altering the globaleslint.config.js.Performance Impact
Type of change
Validation and Testing
vite build) and verified that Rollup correctly generates multiple split JavaScript chunks.GlobalLoaderfallback during slow 3G network simulation.npm test).AuthProvider,QueryClientProvider) remain synchronous and unaffected.Checklist
arialabels where necessaryclose #140