perf(code): replace react-syntax-highlighter and prismjs with the Shiki worker
Route all non-markdown code highlighting through the off-main-thread Shiki worker, removing react-syntax-highlighter and prismjs entirely. - Extend the worker with highlightLines: tokenize a whole block once and return per-line inner HTML, so per-line layouts (diffs, gutters, virtualization) make one worker call instead of one highlighter per line. - Add shared WorkerHighlightedCode (whole-block) and useWorkerHighlightedLines (per-line) primitives. Colors resolve via the --md-syntax-* CSS variables, so theme changes never re-highlight. - Migrate all 12 react-syntax-highlighter call sites: PermissionCard, ToolPart, ContextSidebarTab, ToolOutputDialog (whole block) and DiffPreview/WritePreview (per line). - Migrate VirtualizedCodeBlock off prismjs to the worker, keeping virtua virtualization; whole-block tokenization also restores cross-line syntax context that per-line highlighting lost. - Drop react-syntax-highlighter (+types) from ui and web, prismjs (+types) from ui, and the orphaned create-element type shim.
This commit is contained in:
@@ -7,7 +7,7 @@ import { SimpleMarkdownRenderer } from '../../MarkdownRenderer';
|
||||
import { getToolMetadata } from '@/lib/toolHelpers';
|
||||
import type { ToolPart as ToolPartType, ToolState as ToolStateUnion } from '@opencode-ai/sdk/v2';
|
||||
import { toolDisplayStyles } from '@/lib/typography';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { WorkerHighlightedCode } from '@/components/code/WorkerHighlightedCode';
|
||||
import { useOptionalThemeSystem } from '@/contexts/useThemeSystem';
|
||||
import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
|
||||
import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
@@ -844,7 +844,7 @@ const ToolScrollableTextOutput: React.FC<{
|
||||
metadata: Record<string, unknown> | undefined;
|
||||
input: Record<string, unknown> | undefined;
|
||||
syntaxTheme: { [key: string]: React.CSSProperties };
|
||||
}> = ({ output, part, metadata, input, syntaxTheme }) => {
|
||||
}> = ({ output, part, metadata, input }) => {
|
||||
const { t } = useI18n();
|
||||
const renderedOutput = getToolOutputText(output, part, metadata);
|
||||
const outputLanguage = getToolOutputLanguage(output, part, metadata, input);
|
||||
@@ -910,16 +910,13 @@ const ToolScrollableTextOutput: React.FC<{
|
||||
/>
|
||||
) : (
|
||||
<div className="typography-code pr-12 text-muted-foreground/90">
|
||||
<SyntaxHighlighter
|
||||
style={syntaxTheme}
|
||||
<WorkerHighlightedCode
|
||||
language="json"
|
||||
PreTag="div"
|
||||
customStyle={TOOL_COLLAPSED_CUSTOM_STYLE}
|
||||
codeTagProps={CODE_TAG_PROPS}
|
||||
wrapLongLines
|
||||
>
|
||||
{renderedOutput}
|
||||
</SyntaxHighlighter>
|
||||
code={renderedOutput}
|
||||
style={TOOL_COLLAPSED_CUSTOM_STYLE}
|
||||
codeStyle={CODE_TAG_PROPS.style}
|
||||
wrap
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -928,16 +925,13 @@ const ToolScrollableTextOutput: React.FC<{
|
||||
|
||||
return (
|
||||
<div className={part.tool === 'bash' ? 'typography-code text-muted-foreground/90' : undefined}>
|
||||
<SyntaxHighlighter
|
||||
style={syntaxTheme}
|
||||
<WorkerHighlightedCode
|
||||
language={outputLanguage}
|
||||
PreTag="div"
|
||||
customStyle={TOOL_COLLAPSED_CUSTOM_STYLE}
|
||||
codeTagProps={CODE_TAG_PROPS}
|
||||
wrapLongLines
|
||||
>
|
||||
{renderedOutput}
|
||||
</SyntaxHighlighter>
|
||||
code={renderedOutput}
|
||||
style={TOOL_COLLAPSED_CUSTOM_STYLE}
|
||||
codeStyle={CODE_TAG_PROPS.style}
|
||||
wrap
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user