summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/diff.tsx
diff options
context:
space:
mode:
authorFilip <[email protected]>2026-02-13 12:08:13 +0100
committerGitHub <[email protected]>2026-02-13 05:08:13 -0600
commitebb907d646022d2e7bb8effc164e1f09943d64a9 (patch)
tree65662b4834701f2dc1e2e46da7ed5206341f8ba3 /packages/ui/src/components/diff.tsx
parentb8ee88212639ec63f4fe87555b5e87f74643e76b (diff)
downloadopencode-ebb907d646022d2e7bb8effc164e1f09943d64a9.tar.gz
opencode-ebb907d646022d2e7bb8effc164e1f09943d64a9.zip
fix(desktop): performance optimization for showing large diff & files (#13460)
Diffstat (limited to 'packages/ui/src/components/diff.tsx')
-rw-r--r--packages/ui/src/components/diff.tsx38
1 files changed, 29 insertions, 9 deletions
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx
index 0966db75e..0002232b0 100644
--- a/packages/ui/src/components/diff.tsx
+++ b/packages/ui/src/components/diff.tsx
@@ -1,5 +1,5 @@
-import { checksum } from "@opencode-ai/util/encode"
-import { FileDiff, type SelectedLineRange, VirtualizedFileDiff } from "@pierre/diffs"
+import { sampledChecksum } from "@opencode-ai/util/encode"
+import { FileDiff, type FileDiffOptions, type SelectedLineRange, VirtualizedFileDiff } from "@pierre/diffs"
import { createMediaQuery } from "@solid-primitives/media"
import { createEffect, createMemo, createSignal, onCleanup, splitProps } from "solid-js"
import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre"
@@ -78,14 +78,29 @@ export function Diff<T>(props: DiffProps<T>) {
const mobile = createMediaQuery("(max-width: 640px)")
- const options = createMemo(() => {
- const opts = {
+ const large = createMemo(() => {
+ const before = typeof local.before?.contents === "string" ? local.before.contents : ""
+ const after = typeof local.after?.contents === "string" ? local.after.contents : ""
+ return Math.max(before.length, after.length) > 500_000
+ })
+
+ const largeOptions = {
+ lineDiffType: "none",
+ maxLineDiffLength: 0,
+ tokenizeMaxLineLength: 1,
+ } satisfies Pick<FileDiffOptions<T>, "lineDiffType" | "maxLineDiffLength" | "tokenizeMaxLineLength">
+
+ const options = createMemo<FileDiffOptions<T>>(() => {
+ const base = {
...createDefaultOptions(props.diffStyle),
...others,
}
- if (!mobile()) return opts
+
+ const perf = large() ? { ...base, ...largeOptions } : base
+ if (!mobile()) return perf
+
return {
- ...opts,
+ ...perf,
disableLineNumbers: true,
}
})
@@ -528,12 +543,17 @@ export function Diff<T>(props: DiffProps<T>) {
createEffect(() => {
const opts = options()
- const workerPool = getWorkerPool(props.diffStyle)
+ const workerPool = large() ? getWorkerPool("unified") : getWorkerPool(props.diffStyle)
const virtualizer = getVirtualizer()
const annotations = local.annotations
const beforeContents = typeof local.before?.contents === "string" ? local.before.contents : ""
const afterContents = typeof local.after?.contents === "string" ? local.after.contents : ""
+ const cacheKey = (contents: string) => {
+ if (!large()) return sampledChecksum(contents, contents.length)
+ return sampledChecksum(contents)
+ }
+
instance?.cleanUp()
instance = virtualizer
? new VirtualizedFileDiff<T>(opts, virtualizer, virtualMetrics, workerPool)
@@ -545,12 +565,12 @@ export function Diff<T>(props: DiffProps<T>) {
oldFile: {
...local.before,
contents: beforeContents,
- cacheKey: checksum(beforeContents),
+ cacheKey: cacheKey(beforeContents),
},
newFile: {
...local.after,
contents: afterContents,
- cacheKey: checksum(afterContents),
+ cacheKey: cacheKey(afterContents),
},
lineAnnotations: annotations,
containerWrapper: container,