hermes-agent/apps/desktop/src/components/chat/syntax-diff.tsx
Brooklyn Nicholson 1baea21cfb perf(desktop): load shiki and @streamdown/code on first use, not at boot
The chunk split only helps if nothing on the entry graph statically
imports the heavy libs. Three seams did:

- react-shiki: now behind one lazy() boundary (shiki-block.tsx is its only
  static importer; LazyShiki wraps it with a PlainCode fallback).
- diff-lines.tsx: useShikiHighlighter hook extracted to a lazily-loaded
  syntax-diff.tsx (plain DiffBody fallback — same output Shiki's own
  pre-resolve state showed); codeToTokens becomes a dynamic import that
  runs only once a highlightable diff is on screen.
- @streamdown/code: statically ran createJavaScriptRegexEngine() and built
  full language registries at module scope on every launch. It now loads
  via useCodePlugin() on first markdown mount and swaps into the plugin
  table when it lands; fenced code renders plain until then, identical to
  the delay fallback users already see during streaming.

Interleaved A/B vs main (prod build, warm V8 cache, median of 4, two
alternating rounds): FCP 1100->940ms, DOMContentLoaded 618->542ms,
nav-to-interactive 1312->1123ms on the quiet round; same direction with
larger gaps under load. ~160-190ms off every renderer boot metric.
2026-07-27 20:44:35 -05:00

27 lines
1.1 KiB
TypeScript

'use client'
/**
* The Shiki-highlighted compact diff body, split out of diff-lines.tsx so the
* `react-shiki` static import (and the multi-MB shiki chunk behind it) loads
* lazily on first use instead of on the cold-start path. diff-lines.tsx
* reaches this through `React.lazy` with a plain `DiffBody` fallback.
*/
import type { ReactNode } from 'react'
import { useMemo } from 'react'
import { useShikiHighlighter } from 'react-shiki'
import { DiffBody, type DiffLine, diffLineTransformer } from '@/components/chat/diff-lines'
import { SHIKI_THEME } from '@/components/chat/shiki-highlighter'
export default function SyntaxDiff({ language, lines }: { language: string; lines: DiffLine[] }) {
const code = useMemo(() => lines.map(line => line.text).join('\n'), [lines])
const transformers = useMemo(() => [diffLineTransformer(lines.map(line => line.kind))], [lines])
const highlighted = useShikiHighlighter(code, language, SHIKI_THEME, {
defaultColor: 'light-dark()',
transformers
})
// Until Shiki resolves, show the plain colored diff so there's no flash.
return (highlighted as ReactNode) ?? <DiffBody lines={lines} />
}