diff --git a/apps/desktop/src/app/right-sidebar/review/index.tsx b/apps/desktop/src/app/right-sidebar/review/index.tsx
index 2e50a1f874f5..9fc203c81674 100644
--- a/apps/desktop/src/app/right-sidebar/review/index.tsx
+++ b/apps/desktop/src/app/right-sidebar/review/index.tsx
@@ -202,7 +202,7 @@ export function ReviewPane() {
) : null
) : diff ? (
-
+
) : (
{c.noDiff}
)}
diff --git a/apps/desktop/src/components/chat/diff-lines.tsx b/apps/desktop/src/components/chat/diff-lines.tsx
index eef495c7c54c..179e327a39d0 100644
--- a/apps/desktop/src/components/chat/diff-lines.tsx
+++ b/apps/desktop/src/components/chat/diff-lines.tsx
@@ -559,9 +559,20 @@ interface FileDiffPanelProps {
/** Render an old/new line-number gutter (the full preview diff). The compact
* tool-card + inline review diff leave this off. */
showLineNumbers?: boolean
+ /** Window the rows (fixed-row virtualization) WITHOUT a gutter — for a large
+ * diff in a scrolling pane (the review panel), so only visible rows mount
+ * instead of highlighting every line. `showLineNumbers` implies windowing. */
+ virtualized?: boolean
}
-export function FileDiffPanel({ className, diff, fullText, path, showLineNumbers = false }: FileDiffPanelProps) {
+export function FileDiffPanel({
+ className,
+ diff,
+ fullText,
+ path,
+ showLineNumbers = false,
+ virtualized = false
+}: FileDiffPanelProps) {
const lines = React.useMemo(
() => (fullText != null ? parseFullFileDiff(diff, fullText) : parseDiff(diff)),
[diff, fullText]
@@ -580,32 +591,50 @@ export function FileDiffPanel({ className, diff, fullText, path, showLineNumbers
const language = shikiLanguageForFilename(path)
const canHighlight = Boolean(language) && !exceedsHighlightBudget(fullText ?? diff)
+ const windowed = showLineNumbers || virtualized
- // Full-file preview: we own the rows (tokens rendered inside) so blank lines
- // can't collapse. Compact tool/review diffs let Shiki own the rows.
- const body = !canHighlight ? (
- showLineNumbers ? (
-
- ) : (
-
- )
- ) : fullText != null ? (
+ // Windowed: we own fixed-height rows and render only the visible chunks, so a
+ // large diff never mounts (or Shiki-highlights) every line. Compact tool cards
+ // are small/clamped, so they let Shiki own the rows (SyntaxDiff).
+ const windowedBody = canHighlight ? (
+ ) : (
+
+ )
+
+ const compactBody = !canHighlight ? (
+
+ ) : fullText != null ? (
+
) : (
)
- if (!showLineNumbers) {
+ if (!windowed) {
return (
- {body}
+ {compactBody}
+
+ )
+ }
+
+ // Windowed but no gutter (the review panel): a fixed-row scroller so only the
+ // visible rows render, killing the full-Shiki-of-every-line freeze on large
+ // diffs. The gutter variant (below) adds line numbers on top of the same window.
+ if (!showLineNumbers) {
+ return (
+
)
}
@@ -638,7 +667,7 @@ export function FileDiffPanel({ className, diff, fullText, path, showLineNumbers
))}
{afterRows > 0 && }
- {body}
+ {windowedBody}