From 539e6ed08011e5d1e5b747a2a0152b55c48be12c Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 19 Apr 2026 10:17:10 +0200 Subject: [PATCH] remove lazy loading --- interface/src/AppRouting.tsx | 68 ++++++------- interface/src/AuthenticatedRouting.tsx | 131 ++++++++++++------------- interface/vite.config.ts | 97 ++---------------- 3 files changed, 98 insertions(+), 198 deletions(-) diff --git a/interface/src/AppRouting.tsx b/interface/src/AppRouting.tsx index 91c8f0945..aee79140d 100644 --- a/interface/src/AppRouting.tsx +++ b/interface/src/AppRouting.tsx @@ -1,19 +1,13 @@ -import { type FC, Suspense, lazy, memo, useContext, useEffect, useRef } from 'react'; +import { type FC, memo, useContext, useEffect, useRef } from 'react'; import { Navigate, Route, Routes } from 'react-router'; import { toast } from 'react-toastify'; -import { - LoadingSpinner, - RequireAuthenticated, - RequireUnauthenticated -} from 'components'; +import AuthenticatedRouting from 'AuthenticatedRouting'; +import SignIn from 'SignIn'; +import { RequireAuthenticated, RequireUnauthenticated } from 'components'; import { Authentication, AuthenticationContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; -// Lazy load route components for better code splitting -const SignIn = lazy(() => import('SignIn')); -const AuthenticatedRouting = lazy(() => import('AuthenticatedRouting')); - interface SecurityRedirectProps { readonly message: string; readonly signOut?: boolean; @@ -45,34 +39,32 @@ const AppRouting: FC = memo(() => { return ( - }> - - } - /> - } - /> - - - - } - /> - - - - } - /> - - + + } + /> + } + /> + + + + } + /> + + + + } + /> + ); }); diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index 1be5b0f49..8ace232aa 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -1,86 +1,77 @@ -import { Suspense, lazy, memo, useContext } from 'react'; +import { memo, useContext } from 'react'; import { Navigate, Route, Routes } from 'react-router'; -import { Layout, LoadingSpinner } from 'components'; +import CustomEntities from 'app/main/CustomEntities'; +import Customizations from 'app/main/Customizations'; +import Dashboard from 'app/main/Dashboard'; +import Devices from 'app/main/Devices'; +import Help from 'app/main/Help'; +import Modules from 'app/main/Modules'; +import Scheduler from 'app/main/Scheduler'; +import Sensors from 'app/main/Sensors'; +import UserProfile from 'app/main/UserProfile'; +import APSettings from 'app/settings/APSettings'; +import ApplicationSettings from 'app/settings/ApplicationSettings'; +import DownloadUpload from 'app/settings/DownloadUpload'; +import MqttSettings from 'app/settings/MqttSettings'; +import NTPSettings from 'app/settings/NTPSettings'; +import Settings from 'app/settings/Settings'; +import Network from 'app/settings/network/Network'; +import Security from 'app/settings/security/Security'; +import APStatus from 'app/status/APStatus'; +import Activity from 'app/status/Activity'; +import HardwareStatus from 'app/status/HardwareStatus'; +import MqttStatus from 'app/status/MqttStatus'; +import NTPStatus from 'app/status/NTPStatus'; +import NetworkStatus from 'app/status/NetworkStatus'; +import Status from 'app/status/Status'; +import SystemLog from 'app/status/SystemLog'; +import Version from 'app/status/Version'; +import { Layout } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; -// Lazy load all route components for better code splitting -const Dashboard = lazy(() => import('app/main/Dashboard')); -const Devices = lazy(() => import('app/main/Devices')); -const Sensors = lazy(() => import('app/main/Sensors')); -const Help = lazy(() => import('app/main/Help')); -const Customizations = lazy(() => import('app/main/Customizations')); -const Scheduler = lazy(() => import('app/main/Scheduler')); -const CustomEntities = lazy(() => import('app/main/CustomEntities')); -const Modules = lazy(() => import('app/main/Modules')); -const UserProfile = lazy(() => import('app/main/UserProfile')); - -const Status = lazy(() => import('app/status/Status')); -const HardwareStatus = lazy(() => import('app/status/HardwareStatus')); -const Activity = lazy(() => import('app/status/Activity')); -const SystemLog = lazy(() => import('app/status/SystemLog')); -const MqttStatus = lazy(() => import('app/status/MqttStatus')); -const NTPStatus = lazy(() => import('app/status/NTPStatus')); -const APStatus = lazy(() => import('app/status/APStatus')); -const NetworkStatus = lazy(() => import('app/status/NetworkStatus')); -const Version = lazy(() => import('app/status/Version')); - -const Settings = lazy(() => import('app/settings/Settings')); -const ApplicationSettings = lazy(() => import('app/settings/ApplicationSettings')); -const MqttSettings = lazy(() => import('app/settings/MqttSettings')); -const NTPSettings = lazy(() => import('app/settings/NTPSettings')); -const APSettings = lazy(() => import('app/settings/APSettings')); -const DownloadUpload = lazy(() => import('app/settings/DownloadUpload')); -const Network = lazy(() => import('app/settings/network/Network')); -const Security = lazy(() => import('app/settings/security/Security')); - const AuthenticatedRouting = memo(() => { const { me } = useContext(AuthenticatedContext); return ( - }> - - } /> - } /> - } /> - } /> - } /> + + } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - {me.admin && ( - <> - } /> - } - /> - } /> - } /> - } /> - } /> - } /> + {me.admin && ( + <> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - } /> - } /> + } /> + } /> - } /> - } /> - } /> - - )} + } /> + } /> + } /> + + )} - } /> - - + } /> + ); }); diff --git a/interface/vite.config.ts b/interface/vite.config.ts index 5c288677c..ff34966b7 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -15,7 +15,7 @@ const REPEAT_CHAR = '='; const REPEAT_COUNT = 50; const DEFAULT_OUT_DIR = 'dist'; const ES_TARGET = 'es2020'; -const CHUNK_SIZE_WARNING_LIMIT = 512; +const CHUNK_SIZE_WARNING_LIMIT = 1024; const ASSETS_INLINE_LIMIT = 4096; // Common resolve aliases @@ -130,87 +130,11 @@ const createBasePlugins = ( return plugins; }; -// Manual chunk splitting strategy -const createManualChunks = (detailed = false) => { - return (id: string): string | undefined => { - if (id.includes('node_modules')) { - if (id.includes('preact')) return '@preact'; - if (detailed) { - if (id.includes('react-router')) return '@react-router'; - if (id.includes('@mui/material')) return '@mui-material'; - if (id.includes('@mui/icons-material')) return '@mui-icons'; - if (id.includes('alova')) return '@alova'; - if (id.includes('typesafe-i18n')) return '@i18n'; - if (id.includes('react-toastify')) return '@toastify'; - if (id.includes('@table-library')) return '@table-library'; - if (id.includes('uuid')) return '@uuid'; - if (id.includes('axios') || id.includes('fetch')) return '@http'; - if (id.includes('lodash') || id.includes('ramda')) return '@utils'; - } - return 'vendor'; - } - if (detailed) { - // Group circularly dependent modules together to avoid circular chunk warnings - // components, app, and utils are tightly coupled, so combine them - if ( - id.includes('components/') || - id.includes('app/') || - id.includes('utils/') - ) { - return 'app'; - } - // Keep api separate as it's typically more independent - if (id.includes('api/')) return 'api'; - } - return undefined; - }; +const manualChunks = (id: string): string | undefined => { + if (id.includes('node_modules')) return 'vendor'; + return undefined; }; -// Rolldown-native codeSplitting groups for the production build. -// See: https://rolldown.rs/reference/outputoptions.codesplitting -const createRolldownCodeSplitting = () => ({ - groups: [ - { name: '@preact', test: /[\\/]node_modules[\\/].*preact/, priority: 100 }, - { - name: '@react-router', - test: /[\\/]node_modules[\\/].*react-router/, - priority: 95 - }, - { - name: '@mui-material', - test: /[\\/]node_modules[\\/]@mui[\\/]material/, - priority: 95 - }, - { - name: '@mui-icons', - test: /[\\/]node_modules[\\/]@mui[\\/]icons-material/, - priority: 95 - }, - { name: '@alova', test: /[\\/]node_modules[\\/].*alova/, priority: 90 }, - { name: '@i18n', test: /[\\/]node_modules[\\/].*typesafe-i18n/, priority: 90 }, - { - name: '@toastify', - test: /[\\/]node_modules[\\/].*react-toastify/, - priority: 90 - }, - { - name: '@table-library', - test: /[\\/]node_modules[\\/]@table-library/, - priority: 90 - }, - { name: 'vendor', test: /[\\/]node_modules[\\/]/, priority: 10 }, - // Collapse the lazy-loaded route stubs + shared app/components/utils - // code into one chunk. This cuts firmware-side route count roughly in - // half and speeds up route-matching on every incoming HTTP request. - { - name: 'app', - test: /[\\/](app|components|utils)[\\/]/, - priority: 5 - }, - { name: 'api', test: /[\\/]api[\\/]/, priority: 5 } - ] -}); - // Common build base configuration const createBaseBuildConfig = () => ({ target: ES_TARGET, @@ -335,7 +259,7 @@ export default defineConfig( moduleSideEffects: false }, output: { - manualChunks: createManualChunks(false) + manualChunks } } } @@ -375,17 +299,10 @@ export default defineConfig( chunkFileNames: 'assets/[name]-[hash].js', entryFileNames: 'assets/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash].[ext]', - // Kept as a no-op for documentation/fallback. With Vite 8 - manualChunks: createManualChunks(true), + manualChunks, sourcemap: false } - }, - rolldownOptions: { - output: { - codeSplitting: createRolldownCodeSplitting() - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any + } } }; }