From c7cb6e14a0917470ae0fe792ad493b25a7a0801a Mon Sep 17 00:00:00 2001 From: ddCat <2695092045@qq.com> Date: Thu, 24 Sep 2026 00:05:32 +0800 Subject: [PATCH] =?UTF-8?q?perf(canvas):=20=E7=94=BB=E5=B8=83=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=20-=20=E9=99=8D=E4=BD=8E=E5=A4=A7=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=BC=80=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/canvas/canvas-frame-node.tsx | 18 +- web/src/components/canvas/canvas-mini-map.tsx | 182 ++---- .../components/canvas/canvas-node-content.tsx | 568 ++++++++++++------ web/src/components/canvas/canvas-node.tsx | 35 +- web/src/components/canvas/infinite-canvas.tsx | 3 +- web/src/lib/canvas/canvas-content.ts | 26 +- web/src/lib/canvas/canvas-node-lod.ts | 12 + web/src/lib/canvas/canvas-node-visibility.ts | 6 +- web/src/lib/canvas/task-ticker.ts | 37 ++ .../canvas/canvas-project-world-layers.tsx | 4 + web/src/pages/canvas/project.tsx | 2 + .../pages/canvas/use-canvas-active-tasks.ts | 29 +- .../canvas/use-canvas-project-lifecycle.ts | 26 +- .../pages/canvas/use-canvas-render-model.ts | 80 ++- web/src/services/user-data-sync.ts | 27 +- web/src/stores/canvas/use-canvas-store.ts | 4 + web/test/canvas-node-lod.test.ts | 27 + 17 files changed, 734 insertions(+), 352 deletions(-) create mode 100644 web/src/lib/canvas/canvas-node-lod.ts create mode 100644 web/src/lib/canvas/task-ticker.ts create mode 100644 web/test/canvas-node-lod.test.ts diff --git a/web/src/components/canvas/canvas-frame-node.tsx b/web/src/components/canvas/canvas-frame-node.tsx index e8b2f2c9a..fa9ba016b 100644 --- a/web/src/components/canvas/canvas-frame-node.tsx +++ b/web/src/components/canvas/canvas-frame-node.tsx @@ -6,6 +6,7 @@ import { CometCard } from "@/components/ui/aceternity/comet-card"; import { CanvasFolderPreview } from "@/components/canvas/canvas-folder-preview"; import { CanvasVideoPreviewImage } from "@/components/canvas/canvas-video-preview-image"; import { FRAME_HEADER_HEIGHT, FRAME_PADDING, isCanvasFolderNode } from "@/lib/canvas/canvas-frame"; +import type { CanvasNodeRenderLOD } from "@/lib/canvas/canvas-node-lod"; import { canvasThemes, type CanvasTheme } from "@/lib/canvas-theme"; import { useActiveTheme } from "@/stores/canvas/use-canvas-theme-store"; import { CanvasNodeType, type CanvasFolderStyle, type CanvasFolderTheme, type CanvasNodeData, type Position } from "@/types/canvas"; @@ -14,6 +15,7 @@ type ResizeCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right"; export const CanvasFrameNode = React.memo(function CanvasFrameNode({ data, + renderLOD = "full", dragOffset, childNodes, scale, @@ -33,6 +35,7 @@ export const CanvasFrameNode = React.memo(function CanvasFrameNode({ data: CanvasNodeData; dragOffset?: Position; childNodes: CanvasNodeData[]; + renderLOD?: CanvasNodeRenderLOD; scale: number; isSelected: boolean; isDropTarget: boolean; @@ -51,6 +54,7 @@ export const CanvasFrameNode = React.memo(function CanvasFrameNode({ const collapsed = Boolean(data.metadata?.frame?.collapsed); const folder = isCanvasFolderNode(data); const [editing, setEditing] = useState(false); + const [hovered, setHovered] = useState(false); const [title, setTitle] = useState(data.title); const resizeRef = useRef({ active: false, @@ -148,10 +152,12 @@ export const CanvasFrameNode = React.memo(function CanvasFrameNode({ const active = isSelected || isDropTarget; const linkedFolder = Boolean(data.metadata?.folder?.assetFolderId); + const fullDetail = renderLOD === "full" || hovered || editing; return (