🛠 Build optimizations (chunking and lazy-loading)

This commit is contained in:
2026-03-06 12:37:45 -05:00
parent 46e683859e
commit 7818c6f290
4 changed files with 58 additions and 26 deletions

View File

@@ -1,4 +1,4 @@
import React, { ReactElement, useState } from "react"; import React, { ReactElement, Suspense, useState } from "react";
import { isNil } from "lodash"; import { isNil } from "lodash";
export const TabControls = (props): ReactElement => { export const TabControls = (props): ReactElement => {
@@ -47,9 +47,11 @@ export const TabControls = (props): ReactElement => {
</nav> </nav>
</div> </div>
</div> </div>
{filteredTabs.map(({ id, content }) => { <Suspense>
return currentActive === id ? content : null; {filteredTabs.map(({ id, content }) => {
})} return currentActive === id ? content : null;
})}
</Suspense>
</> </>
); );
}; };

View File

@@ -1,11 +1,12 @@
import React from "react"; import React, { lazy } from "react";
import { isNil, isEmpty } from "lodash"; import { isNil, isEmpty } from "lodash";
import { VolumeInformation } from "./Tabs/VolumeInformation";
import { ComicInfoXML } from "./Tabs/ComicInfoXML"; const VolumeInformation = lazy(() => import("./Tabs/VolumeInformation").then(m => ({ default: m.VolumeInformation })));
import { ArchiveOperations } from "./Tabs/ArchiveOperations"; const ComicInfoXML = lazy(() => import("./Tabs/ComicInfoXML").then(m => ({ default: m.ComicInfoXML })));
import AcquisitionPanel from "./AcquisitionPanel"; const ArchiveOperations = lazy(() => import("./Tabs/ArchiveOperations").then(m => ({ default: m.ArchiveOperations })));
import TorrentSearchPanel from "./TorrentSearchPanel"; const AcquisitionPanel = lazy(() => import("./AcquisitionPanel"));
import DownloadsPanel from "./DownloadsPanel"; const TorrentSearchPanel = lazy(() => import("./TorrentSearchPanel"));
const DownloadsPanel = lazy(() => import("./DownloadsPanel"));
interface TabConfig { interface TabConfig {
id: number; id: number;

View File

@@ -1,22 +1,21 @@
import React from "react"; import { lazy, Suspense } from "react";
import { render } from "react-dom";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root")!);
import App from "./components/App"; import App from "./components/App";
import { createBrowserRouter, RouterProvider } from "react-router-dom"; import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Settings from "./components/Settings/Settings";
import { ErrorPage } from "./components/shared/ErrorPage"; import { ErrorPage } from "./components/shared/ErrorPage";
const rootEl = document.getElementById("root"); import "./shared/utils/i18n.util";
const root = createRoot(rootEl);
import i18n from "./shared/utils/i18n.util";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import Import from "./components/Import/Import";
import Dashboard from "./components/Dashboard/Dashboard"; const Settings = lazy(() => import("./components/Settings/Settings"));
import Search from "./components/Search/Search"; const Import = lazy(() => import("./components/Import/Import"));
import TabulatedContentContainer from "./components/Library/TabulatedContentContainer"; const Dashboard = lazy(() => import("./components/Dashboard/Dashboard"));
import { ComicDetailContainer } from "./components/ComicDetail/ComicDetailContainer"; const Search = lazy(() => import("./components/Search/Search"));
import Volumes from "./components/Volumes/Volumes"; const TabulatedContentContainer = lazy(() => import("./components/Library/TabulatedContentContainer"));
import VolumeDetails from "./components/VolumeDetail/VolumeDetail"; const ComicDetailContainer = lazy(() => import("./components/ComicDetail/ComicDetailContainer").then(m => ({ default: m.ComicDetailContainer })));
import WantedComics from "./components/WantedComics/WantedComics"; const Volumes = lazy(() => import("./components/Volumes/Volumes"));
const VolumeDetails = lazy(() => import("./components/VolumeDetail/VolumeDetail"));
const WantedComics = lazy(() => import("./components/WantedComics/WantedComics"));
const queryClient = new QueryClient({ const queryClient = new QueryClient({
defaultOptions: { defaultOptions: {
@@ -55,6 +54,8 @@ const router = createBrowserRouter([
root.render( root.render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<RouterProvider router={router} /> <Suspense>
<RouterProvider router={router} />
</Suspense>
</QueryClientProvider>, </QueryClientProvider>,
); );

View File

@@ -7,6 +7,34 @@ export default defineConfig({
base: "", base: "",
build: { build: {
target: "esnext", target: "esnext",
rollupOptions: {
output: {
manualChunks: {
"react-vendor": ["react", "react-dom", "react-router", "react-router-dom"],
"query-vendor": ["@tanstack/react-query", "@tanstack/react-table"],
"ui-vendor": [
"styled-components",
"react-toastify",
"react-select",
"react-modal",
"react-sliding-pane",
"embla-carousel-react",
"react-day-picker",
"react-loader-spinner",
],
"utils-vendor": [
"lodash",
"date-fns",
"dayjs",
"axios",
"rxjs",
"socket.io-client",
"i18next",
"react-i18next",
],
},
},
},
}, },
esbuild: { esbuild: {
supported: { supported: {