Skip to content

Lazy-load syntax highlighter in markdown text renderer #1015

@MODSetter

Description

@MODSetter

Description

markdown-text.tsx statically imports react-syntax-highlighter with Prism themes (lines 14-15). This is the default renderer for every assistant message, so the highlighter (~50-100KB with themes) loads even for messages that contain no code blocks.

Vercel React Best Practices Rule: bundle-dynamic-imports (2.4)

File to change

  • surfsense_web/components/assistant-ui/markdown-text.tsx

What to do

  1. Extract the code block rendering into a separate component file, e.g. surfsense_web/components/assistant-ui/syntax-highlight-code.tsx:
"use client";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { materialDark, materialLight } from "react-syntax-highlighter/dist/esm/styles/prism";
import { useTheme } from "next-themes";
// ... export the code rendering component that currently lives inside markdown-text.tsx
  1. In markdown-text.tsx, remove the static react-syntax-highlighter imports (lines 14-15) and use next/dynamic:
import dynamic from "next/dynamic";

const SyntaxHighlightCode = dynamic(
  () => import("./syntax-highlight-code").then(m => ({ default: m.SyntaxHighlightCode })),
  { ssr: false, loading: () => <pre className="animate-pulse bg-muted rounded-md p-4 h-20" /> }
);
  1. Update the markdown components config to use SyntaxHighlightCode instead of inline SyntaxHighlighter.

Acceptance criteria

  • Messages without code blocks don't load react-syntax-highlighter
  • Code blocks still render with proper syntax highlighting and theme support (dark/light)
  • A subtle loading skeleton appears briefly for the first code block in a session
  • Bundle size for the chat page is reduced

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions