Highlight code against single theme when mode is resolved - #259
Open
benvinegar wants to merge 1 commit into
Open
Highlight code against single theme when mode is resolved#259benvinegar wants to merge 1 commit into
benvinegar wants to merge 1 commit into
Conversation
shiki tokenizes once PER THEME, so asking for a light/dark pair costs exactly twice as much as asking for one. We asked for both on every render and then threw one away: shikiSchemeCss flipped to the dark colors with CSS, and the viewer had already told us which scheme it resolved — Card.tsx appends &mode= to every surface iframe src. Highlight against the single resolved theme when mode is pinned, and drop the now-unnecessary flip rule. An unpinned direct load of /s/:id (someone opening the link outside the viewer) still gets both themes and follows the OS through the existing media query. Measured with the benchmark suite, 1402-line TypeScript surface: code/large 1.14 s -> 543 ms (-52%) code/large document 751 KB -> 529 KB (-30%) markdown/large 51.9 ms -> 27.9 ms (-45%) theme switch burst 99.9 ms -> 53.8 ms (-45%) Through the real route (/s/:id?mode=dark): 1109 ms -> 582 ms. Output is visually identical: dual-theme emitted the light color inline plus a --shiki-dark custom property and overrode it with `color: var(--shiki-dark) !important`; single-theme emits the same final color inline. The token color sequences are identical, and the pre background resolves to the same value either way. Terminal, diff, html and mermaid surfaces are untouched — none of them take the dual-theme path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MGMuudU8anVrxB7sjY9hpt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Optimize code highlighting performance by tokenizing against a single theme when the color scheme is already known, rather than always tokenizing against both light and dark themes and discarding one with CSS.
Key Changes
Refactored
shikiPair()→shikiThemeOptions(): Now accepts boththemeandmodeparameters. Whenmodeis resolved ("light" or "dark"), returns a single-theme option; whenmodeis undefined, returns the light/dark pair for unpinned loads that follow the OS via media query.Updated
shikiSchemeCss(): Simplified logic to return empty string for any resolved mode (since colors are already correct inline), and only emit the media query when mode is undefined.Type safety: Introduced
ShikiThemeOptionsunion type to distinguish between single-theme ({ theme: string }) and dual-theme ({ themes: { light: string; dark: string } }) configurations.Updated call sites:
renderMarkdown()andrenderCode()now passopts.modetoshikiThemeOptions()and use the resulting options with shiki'scodeToHtml().Performance Impact
/s/:idopened outside the viewer): Still receive both themes and follow OS via media query, no regressionImplementation Details
The viewer always appends
&mode=to surface iframe sources, so it can tell the server which scheme it resolved. This change leverages that signal: when mode is known, shiki only tokenizes once instead of twice, eliminating wasted work that was being discarded by CSS. Only direct unpinned loads need both themes, and they continue to work as before.https://claude.ai/code/session_01MGMuudU8anVrxB7sjY9hpt