From 2670eb2925cd78e3d09992a50d56559eace45ac3 Mon Sep 17 00:00:00 2001 From: chamiakJ Date: Sat, 21 Jun 2025 19:15:13 +0530 Subject: [PATCH] feat(lazy-loading): implement lazy loading and suspense for improved performance - Added lazy loading for NotFoundPage and TaskListFilters components to enhance initial load times. - Wrapped lazy-loaded components in Suspense boundaries to provide loading states and improve user experience. - Updated Vite configuration to optimize chunking strategy and preserve module signatures for better dependency management. --- worklenz-frontend/index.html | 2 +- .../src/app/routes/not-found-route.tsx | 12 +++++++++--- .../projectView/board/project-view-board.tsx | 9 ++++++--- .../taskList/project-view-task-list.tsx | 8 +++++--- worklenz-frontend/vite.config.ts | 19 +++++++++++-------- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/worklenz-frontend/index.html b/worklenz-frontend/index.html index ba93ca2c..15afe141 100644 --- a/worklenz-frontend/index.html +++ b/worklenz-frontend/index.html @@ -13,7 +13,7 @@ Worklenz - + diff --git a/worklenz-frontend/src/app/routes/not-found-route.tsx b/worklenz-frontend/src/app/routes/not-found-route.tsx index 4059609f..3c25e979 100644 --- a/worklenz-frontend/src/app/routes/not-found-route.tsx +++ b/worklenz-frontend/src/app/routes/not-found-route.tsx @@ -1,10 +1,16 @@ -import React from 'react'; +import React, { lazy, Suspense } from 'react'; import { RouteObject } from 'react-router-dom'; -import NotFoundPage from '@/pages/404-page/404-page'; +import { SuspenseFallback } from '@/components/suspense-fallback/suspense-fallback'; + +const NotFoundPage = lazy(() => import('@/pages/404-page/404-page')); const notFoundRoute: RouteObject = { path: '*', - element: , + element: ( + }> + + + ), }; export default notFoundRoute; diff --git a/worklenz-frontend/src/pages/projects/projectView/board/project-view-board.tsx b/worklenz-frontend/src/pages/projects/projectView/board/project-view-board.tsx index 3f886223..3400cb86 100644 --- a/worklenz-frontend/src/pages/projects/projectView/board/project-view-board.tsx +++ b/worklenz-frontend/src/pages/projects/projectView/board/project-view-board.tsx @@ -1,6 +1,7 @@ -import { useEffect, useState, useRef, useMemo, useCallback } from 'react'; +import { useEffect, useState, useRef, useMemo, useCallback, lazy, Suspense } from 'react'; import { useAppSelector } from '@/hooks/useAppSelector'; -import TaskListFilters from '../taskList/task-list-filters/task-list-filters'; + +const TaskListFilters = lazy(() => import('../taskList/task-list-filters/task-list-filters')); import { Flex, Skeleton } from 'antd'; import BoardSectionCardContainer from './board-section/board-section-container'; import { @@ -537,7 +538,9 @@ const ProjectViewBoard = () => { return ( - + Loading filters...}> + + import('./task-list-filters/task-list-filters')); import TaskGroupWrapperOptimized from './task-group-wrapper-optimized'; import { useAppSelector } from '@/hooks/useAppSelector'; import { useAppDispatch } from '@/hooks/useAppDispatch'; @@ -100,7 +100,9 @@ const ProjectViewTaskList = () => { return ( {/* Filters load independently and don't block the main content */} - + Loading filters...}> + + {isEmptyState ? ( diff --git a/worklenz-frontend/vite.config.ts b/worklenz-frontend/vite.config.ts index 6515fbd1..0cbd058c 100644 --- a/worklenz-frontend/vite.config.ts +++ b/worklenz-frontend/vite.config.ts @@ -72,7 +72,7 @@ export default defineConfig(({ command, mode }) => { output: { // **Optimized Chunking Strategy** manualChunks(id) { - // Core React libraries + // Core React libraries - keep together to avoid dependency issues if (id.includes('react') || id.includes('react-dom')) { return 'react-vendor'; } @@ -82,16 +82,11 @@ export default defineConfig(({ command, mode }) => { return 'react-router'; } - // Ant Design (keep separate for better caching) - if (id.includes('antd') && !id.includes('@ant-design/icons')) { + // Ant Design and Icons together to share React context + if (id.includes('antd') || id.includes('@ant-design/icons')) { return 'antd'; } - // Icons (if using ant design icons) - if (id.includes('@ant-design/icons')) { - return 'antd-icons'; - } - // Internationalization if (id.includes('i18next')) { return 'i18n'; @@ -124,6 +119,9 @@ export default defineConfig(({ command, mode }) => { // **External dependencies (if any should be externalized)** external: [], + + // **Preserve modules to avoid context issues** + preserveEntrySignatures: 'strict', }, // **Experimental features for better performance** @@ -138,10 +136,15 @@ export default defineConfig(({ command, mode }) => { include: [ 'react', 'react-dom', + 'react/jsx-runtime', + 'antd', + '@ant-design/icons', ], exclude: [ // Add any packages that should not be pre-bundled ], + // Force pre-bundling to avoid runtime issues + force: true, }, // **Define global constants**