Skip to content

Lazy-load DocumentTabContent in LayoutShell to reduce dashboard shell bundle #1242

@MODSetter

Description

@MODSetter

Description

surfsense_web/components/layout/ui/shell/LayoutShell.tsx statically imports DocumentTabContent (line 28), but that component is only rendered when a document tab is active (lines 132–140).

DocumentTabContent itself statically imports heavy dependencies (PlateEditor and MarkdownViewer), which in turn pull in the Plate editor stack, lowlight language grammars, Streamdown, KaTeX CSS, etc.

Result: every user loading the dashboard shell (even those who never open a document tab) pays the cost of these heavy dependencies.

Current code

surfsense_web/components/layout/ui/shell/LayoutShell.tsx line 28:

import { DocumentTabContent } from "../tabs/DocumentTabContent";

Usage (lines 132–140):

{isDocumentTab && activeTab.documentId && activeTab.searchSpaceId ? (
    <div className="flex-1 overflow-hidden">
        <DocumentTabContent
            key={activeTab.documentId}
            documentId={activeTab.documentId}
            searchSpaceId={activeTab.searchSpaceId}
            title={activeTab.title}
        />
    </div>
) : (
    <div className={cn("flex-1", isChatPage ? "overflow-hidden" : "overflow-auto")}>
        {children}
    </div>
)}

What to do

  1. Replace the static import with a dynamic import using next/dynamic:
import dynamic from "next/dynamic";

const DocumentTabContent = dynamic(
    () => import("../tabs/DocumentTabContent").then((m) => ({ default: m.DocumentTabContent })),
    {
        loading: () => (
            <div className="flex-1 flex items-center justify-center">
                {/* optional: lightweight skeleton */}
            </div>
        ),
    }
);
  1. If DocumentTabContent.tsx uses browser-only APIs you may add ssr: false. Check the file first — if it has any server-safe code paths, keep SSR enabled.

  2. Keep the existing usage block unchanged.

Verify:

  • Opening a document tab still renders the document content correctly (no errors)
  • The document editor still functions (editing, saving)
  • next build succeeds
  • Ideally run next build before/after and compare the main shell chunk size to confirm the improvement

Acceptance criteria

  • DocumentTabContent is loaded via next/dynamic
  • Dashboard shell no longer pulls Plate/Streamdown/KaTeX statically
  • Document tab behavior is unchanged
  • next build succeeds

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions