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) + } + /> + )} + /> +
); });