diff --git a/src/App.tsx b/src/App.tsx index dec5a283..4c19dd64 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useCallback, useRef } from 'react'; +import React, { useEffect, useState, useCallback, useRef, lazy, Suspense } from 'react'; import { showToast } from './utils/toast'; import { BrowserRouter, Routes, Route, Navigate, useNavigate, useLocation } from 'react-router-dom'; import { listen } from '@tauri-apps/api/event'; @@ -14,6 +14,7 @@ import { useIsMobile } from './hooks/useIsMobile'; import LiveSearch from './components/LiveSearch'; import NowPlayingDropdown from './components/NowPlayingDropdown'; import QueuePanel from './components/QueuePanel'; +// Eager — main browsing flow, loaded on first paint import Home from './pages/Home'; import Albums from './pages/Albums'; import Artists from './pages/Artists'; @@ -22,23 +23,27 @@ import NewReleases from './pages/NewReleases'; import Favorites from './pages/Favorites'; import RandomMix from './pages/RandomMix'; import RandomLanding from './pages/RandomLanding'; -import Settings from './pages/Settings'; import Login from './pages/Login'; import AlbumDetail from './pages/AlbumDetail'; -import LabelAlbums from './pages/LabelAlbums'; -import Statistics from './pages/Statistics'; import MostPlayed from './pages/MostPlayed'; -import Help from './pages/Help'; import RandomAlbums from './pages/RandomAlbums'; import SearchResults from './pages/SearchResults'; -import AdvancedSearch from './pages/AdvancedSearch'; import Playlists from './pages/Playlists'; import PlaylistDetail from './pages/PlaylistDetail'; -import InternetRadio from './pages/InternetRadio'; -import FolderBrowser from './pages/FolderBrowser'; -import DeviceSync from './pages/DeviceSync'; import NowPlayingPage from './pages/NowPlaying'; -import WhatsNew from './pages/WhatsNew'; + +// Lazy — visited rarely or on-demand. Each becomes its own chunk so the +// initial bundle stays smaller and these pages don't block first paint. +const Settings = lazy(() => import('./pages/Settings')); +const Statistics = lazy(() => import('./pages/Statistics')); +const Help = lazy(() => import('./pages/Help')); +const WhatsNew = lazy(() => import('./pages/WhatsNew')); +const DeviceSync = lazy(() => import('./pages/DeviceSync')); +const OfflineLibrary = lazy(() => import('./pages/OfflineLibrary')); +const LabelAlbums = lazy(() => import('./pages/LabelAlbums')); +const AdvancedSearch = lazy(() => import('./pages/AdvancedSearch')); +const FolderBrowser = lazy(() => import('./pages/FolderBrowser')); +const InternetRadio = lazy(() => import('./pages/InternetRadio')); import MiniPlayer from './components/MiniPlayer'; import { initMiniPlayerBridgeOnMain } from './utils/miniPlayerBridge'; import FullscreenPlayer from './components/FullscreenPlayer'; @@ -50,7 +55,6 @@ import TooltipPortal from './components/TooltipPortal'; import ConnectionIndicator from './components/ConnectionIndicator'; import LastfmIndicator from './components/LastfmIndicator'; import OfflineBanner from './components/OfflineBanner'; -import OfflineLibrary from './pages/OfflineLibrary'; import Genres from './pages/Genres'; import GenreDetail from './pages/GenreDetail'; import ExportPickerModal from './components/ExportPickerModal'; @@ -401,35 +405,37 @@ function AppShell() { )}
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - : } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + : } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + +
diff --git a/vite.config.ts b/vite.config.ts index 8ab53c0e..56ee0385 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -27,5 +27,25 @@ export default defineConfig({ target: process.env.TAURI_ENV_PLATFORM === "windows" ? "chrome105" : "safari13", minify: !process.env.TAURI_ENV_DEBUG ? "esbuild" : false, sourcemap: !!process.env.TAURI_ENV_DEBUG, + rollupOptions: { + output: { + // Vendor chunks isolate dependencies that change rarely from app code, + // so a normal app update doesn't invalidate the cached vendor bundles + // (helps especially with the Tauri updater pulling deltas). + manualChunks: { + react: ["react", "react-dom", "react-router-dom"], + tauri: [ + "@tauri-apps/api", + "@tauri-apps/plugin-shell", + "@tauri-apps/plugin-dialog", + "@tauri-apps/plugin-fs", + "@tauri-apps/plugin-process", + "@tauri-apps/plugin-store", + "@tauri-apps/plugin-updater", + ], + i18n: ["i18next", "react-i18next"], + }, + }, + }, }, });