Refactor AIPage and EQPage components to use lazy loading with PageSuspense for improved performance; update vite.config.ts to adjust chunking strategy and increase chunk size warning limit for better handling of large libraries.

This commit is contained in:
yangy
2026-05-27 18:07:36 +08:00
parent b59a7bb583
commit e6b7dcc89c
5 changed files with 70 additions and 44 deletions
+19 -4
View File
@@ -1,15 +1,16 @@
import { lazy } from "react";
import { Toaster } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { Route, Switch, Router } from "wouter";
import { useHashLocation } from "wouter/use-hash-location";
import ErrorBoundary from "./components/ErrorBoundary";
import PageSuspense from "./components/PageSuspense";
import { ThemeProvider } from "./contexts/ThemeContext";
import { DeviceProvider } from "./contexts/DeviceContext";
import Home from "./pages/Home";
import NotFound from "./pages/NotFound";
import Dashboard from "./pages/Dashboard";
import AudioPage from "./pages/AudioPage";
import EQPage from "./pages/EQPage";
import EffectsPage from "./pages/EffectsPage";
import BluetoothPage from "./pages/BluetoothPage";
import DspPage from "./pages/DspPage";
@@ -18,14 +19,28 @@ import SystemPage from "./pages/SystemPage";
import IOPage from "./pages/IOPage";
import VUPage from "./pages/VUPage";
import SelectPage from "./pages/SelectPage";
import AIPage from "./pages/AIPage";
import CommunityPage from "./pages/CommunityPage";
import { AIDrawerProvider } from "./contexts/AIDrawerContext";
import DesktopAIShell from "./components/DesktopAIShell";
import { appShellColumnClass, appShellGutterClass } from "./lib/appShell";
const EQPage = lazy(() => import("./pages/EQPage"));
const AIPage = lazy(() => import("./pages/AIPage"));
function AIPageRoute() {
return <AIPage />;
return (
<PageSuspense>
<AIPage />
</PageSuspense>
);
}
function EQPageRoute() {
return (
<PageSuspense>
<EQPage />
</PageSuspense>
);
}
function AppRouter() {
@@ -34,7 +49,7 @@ function AppRouter() {
<Route path="/" component={Home} />
<Route path="/dashboard" component={Dashboard} />
<Route path="/audio" component={AudioPage} />
<Route path="/eq" component={EQPage} />
<Route path="/eq" component={EQPageRoute} />
<Route path="/effects" component={EffectsPage} />
<Route path="/bluetooth" component={BluetoothPage} />
<Route path="/dsp" component={DspPage} />
+7 -2
View File
@@ -1,4 +1,4 @@
import AIPage from "@/pages/AIPage";
import PageSuspense from "@/components/PageSuspense";
import { useAIDrawer } from "@/contexts/AIDrawerContext";
import { useIsLgUp } from "@/hooks/useIsLgUp";
import { cn } from "@/lib/utils";
@@ -7,10 +7,13 @@ import {
useCallback,
useEffect,
useRef,
lazy,
type ReactNode,
type RefObject,
} from "react";
const AIPage = lazy(() => import("@/pages/AIPage"));
function SplitDivider({
containerRef,
onResize,
@@ -114,7 +117,9 @@ export default function DesktopAIShell({ children }: { children: ReactNode }) {
className="flex h-full min-h-0 min-w-0 flex-col overflow-hidden border-l border-white/[0.08] bg-[#0d1117]"
style={{ flex: `${splitPercent} 1 0%` }}
>
<AIPage variant="split" onClose={() => setOpen(false)} />
<PageSuspense>
<AIPage variant="split" onClose={() => setOpen(false)} />
</PageSuspense>
</div>
</>
)}
+13
View File
@@ -0,0 +1,13 @@
import { Suspense, type ReactNode } from "react";
function PageFallback() {
return (
<div className="flex min-h-dvh items-center justify-center bg-[#0d1117]">
<span className="text-sm text-white/40">Loading</span>
</div>
);
}
export default function PageSuspense({ children }: { children: ReactNode }) {
return <Suspense fallback={<PageFallback />}>{children}</Suspense>;
}
+19 -18
View File
@@ -378,6 +378,25 @@ export default function Home() {
};
}, []);
const volumePassthroughActive =
(deviceState?.dacVolumeDirect ?? 0) === 1 || (deviceState?.dacVolumeDirect ?? 0) === 2;
const volumeControlsLocked =
volumePassthroughActive &&
(deviceState?.output ?? 0) !== HEADPHONE_OUTPUT_INDEX;
const volumePassthroughHint =
homeText.volumePassthroughLockedHint ??
homeText.volumePassthroughLockedToast ??
"当前为音量直通模式,无法调节音量";
const guardVolumeChange = useCallback(
(action: () => void) => {
if (volumeControlsLocked) return;
action();
},
[volumeControlsLocked],
);
if (!isConnected) return <ConnectionPlaceholder />;
const ds = deviceState!;
@@ -393,24 +412,6 @@ export default function Home() {
// 换算为 volume 单位:0.5/1/2/3 dB -> 1/2/4/6
const fineVolumeStep = [1, 2, 4, 6][ds.soundStep ?? 1] ?? 1;
const volumePassthroughActive =
(ds.dacVolumeDirect ?? 0) === 1 || (ds.dacVolumeDirect ?? 0) === 2;
const volumeControlsLocked =
volumePassthroughActive && ds.output !== HEADPHONE_OUTPUT_INDEX;
const volumePassthroughHint =
homeText.volumePassthroughLockedHint ??
homeText.volumePassthroughLockedToast ??
"当前为音量直通模式,无法调节音量";
const guardVolumeChange = useCallback(
(action: () => void) => {
if (volumeControlsLocked) return;
action();
},
[volumeControlsLocked],
);
// Slider fill % (0-200 → 0-100%)
const fillPct = (localVol / 200) * 100;
// Knob angle (map 0..200 -> -135..+135 degrees)