diff --git a/apps/code/src/renderer/features/code-review/components/CloudReviewPage.tsx b/apps/code/src/renderer/features/code-review/components/CloudReviewPage.tsx
index 001f7324f..0c51cd16b 100644
--- a/apps/code/src/renderer/features/code-review/components/CloudReviewPage.tsx
+++ b/apps/code/src/renderer/features/code-review/components/CloudReviewPage.tsx
@@ -10,6 +10,7 @@ import { useMemo } from "react";
import type { DiffOptions } from "../types";
import type { PrCommentThread } from "../utils/prCommentAnnotations";
import { InteractiveFileDiff } from "./InteractiveFileDiff";
+import { LazyDiff } from "./LazyDiff";
import {
DeferredDiffPlaceholder,
DiffFileHeader,
@@ -102,15 +103,17 @@ export function CloudReviewPage({ task }: CloudReviewPageProps) {
return (
- toggleFile(file.path)}
- commentThreads={showReviewComments ? commentThreads : undefined}
- />
+
+ toggleFile(file.path)}
+ commentThreads={showReviewComments ? commentThreads : undefined}
+ />
+
);
})}
diff --git a/apps/code/src/renderer/features/code-review/components/LazyDiff.tsx b/apps/code/src/renderer/features/code-review/components/LazyDiff.tsx
new file mode 100644
index 000000000..73bcf400b
--- /dev/null
+++ b/apps/code/src/renderer/features/code-review/components/LazyDiff.tsx
@@ -0,0 +1,31 @@
+import { type ReactNode, useEffect, useRef, useState } from "react";
+
+const VISIBILITY_MARGIN = 1500;
+
+interface LazyDiffProps {
+ children: ReactNode;
+}
+
+export function LazyDiff({ children }: LazyDiffProps) {
+ const ref = useRef(null);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ const el = ref.current;
+ if (!el || mounted) return;
+
+ const observer = new IntersectionObserver(
+ ([entry]) => {
+ if (entry.isIntersecting) {
+ setMounted(true);
+ observer.disconnect();
+ }
+ },
+ { rootMargin: `${VISIBILITY_MARGIN}px 0px` },
+ );
+ observer.observe(el);
+ return () => observer.disconnect();
+ }, [mounted]);
+
+ return {mounted ? children : null}
;
+}
diff --git a/apps/code/src/renderer/features/code-review/components/ReviewPage.tsx b/apps/code/src/renderer/features/code-review/components/ReviewPage.tsx
index 8cb5318fb..8ed535515 100644
--- a/apps/code/src/renderer/features/code-review/components/ReviewPage.tsx
+++ b/apps/code/src/renderer/features/code-review/components/ReviewPage.tsx
@@ -11,6 +11,7 @@ import { useMemo } from "react";
import { useReviewDiffs } from "../hooks/useReviewDiffs";
import type { DiffOptions } from "../types";
import { InteractiveFileDiff } from "./InteractiveFileDiff";
+import { LazyDiff } from "./LazyDiff";
import {
DeferredDiffPlaceholder,
type DeferredReason,
@@ -108,14 +109,16 @@ export function ReviewPage({ task }: ReviewPageProps) {
const isCollapsed = collapsedFiles.has(key);
return (
- toggleFile(key)}
- taskId={taskId}
- />
+
+ toggleFile(key)}
+ taskId={taskId}
+ />
+
);
})}
@@ -183,22 +186,24 @@ function FileDiffList({
return (
- (
- toggleFile(key)}
- onOpenFile={() =>
- openFile(taskId, `${repoPath}/${filePath}`, false)
- }
- />
- )}
- />
+
+ (
+ toggleFile(key)}
+ onOpenFile={() =>
+ openFile(taskId, `${repoPath}/${filePath}`, false)
+ }
+ />
+ )}
+ />
+
);
});