perf(web-read-card): lazy-load read grammars and guard empty-window copy
Only TypeScript, shell, and JSON grammars load at Web boot; the read card's wider langFromPath extension set loads through dynamic imports on first use, so a session that never opens a read card in one of those languages avoids ~1.6 MB of grammar modules and their synchronous init. ReadBlock/CodeBlock re-render on grammar-load via useSyncExternalStore, picking up highlighting once the grammar registers. ReadBlock hides the copy control on an empty window (a successful read of an empty file settles to lines: [] with card:'read'), matching TerminalBlock so it cannot wipe the clipboard.
This commit is contained in:
8 files changed
+216
-71
No files matched your search
@@ -4,10 +4,10 @@
|
||||
// plain fallback for everything else. Chrome (language banner + copy) matches
|
||||
// deepsuite `@deepseek/md` code blocks; token colors stay on `--shiki-*`.
|
||||
|
||||
import { useCallback, useMemo, useRef, useState } from 'react'
|
||||
import { useCallback, useMemo, useRef, useState, useSyncExternalStore } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { writeClipboard } from '../clipboard.ts'
|
||||
import { highlightToHtml } from './highlight.ts'
|
||||
import { grammarLoadCount, highlightToHtml, subscribeGrammarLoaded } from './highlight.ts'
|
||||
import css from './CodeBlock.module.css'
|
||||
|
||||
export interface CodeBlockProps {
|
||||
@@ -21,7 +21,11 @@ export interface CodeBlockProps {
|
||||
|
||||
export function CodeBlock({ code, lang, className }: CodeBlockProps) {
|
||||
const trimmed = code.endsWith('\n') ? code.slice(0, -1) : code
|
||||
const html = useMemo(() => highlightToHtml(trimmed, lang), [trimmed, lang])
|
||||
// Re-render when a lazy grammar finishes loading, so a fence that showed plain
|
||||
// text while its language's grammar imported picks up highlighting. The
|
||||
// snapshot value is opaque; only its change across renders drives the memo.
|
||||
const loaded = useSyncExternalStore(subscribeGrammarLoaded, grammarLoadCount, grammarLoadCount)
|
||||
const html = useMemo(() => highlightToHtml(trimmed, lang), [trimmed, lang, loaded])
|
||||
const rootRef = useRef<HTMLDivElement>(null)
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user