Browse Source

卡顿优化

feature/0722ui
Luckyu_js 4 days ago
parent
commit
cb5169c4c4
  1. 2
      src/components/AssetLibraryDrawer.tsx
  2. 69
      src/components/WorkflowCanvas.tsx

2
src/components/AssetLibraryDrawer.tsx

@ -138,7 +138,7 @@ function MediaThumb({ item }: { item: UserFileItem }) {
const thumbUrl = getTreeThumbUrl(item);
if ((kind === "image" || kind === "video") && thumbUrl) {
return <img src={thumbUrl} alt="" className="h-full w-full object-cover" />;
return <img src={thumbUrl} alt="" className="h-full w-full object-contain" />;
}
if (kind === "video") {

69
src/components/WorkflowCanvas.tsx

@ -362,6 +362,8 @@ function isLocalKeyboardTarget(target: EventTarget | null): boolean {
const FIT_VIEW_OPTIONS = { maxZoom: 1 };
const CANVAS_MIN_ZOOM = 0.15;
const CANVAS_MAX_ZOOM = 4;
const CANVAS_MIN_ZOOM_PERCENT = CANVAS_MIN_ZOOM * 100;
const CANVAS_MAX_ZOOM_PERCENT = CANVAS_MAX_ZOOM * 100;
const WHEEL_ZOOM_FACTOR = 1.15;
// Connection validation rules
@ -610,6 +612,8 @@ export function WorkflowCanvas() {
const tutorialViewportSet = useRef(false);
const gestureZoomStartRef = useRef<{ zoom: number } | null>(null);
const lastCanvasPointerFlowPositionRef = useRef<ScreenPoint | null>(null);
const pendingDragPositionChangesRef = useRef<Map<string, NodeChange<WorkflowNode>>>(new Map());
const pendingDragPositionFrameRef = useRef<number | null>(null);
const [boxSelectionRect, setBoxSelectionRect] = useState<FlowRect | null>(null);
const onNodesChange = useCallback((changes: NodeChange<WorkflowNode>[]) => {
@ -624,10 +628,62 @@ export function WorkflowCanvas() {
}
}, [storeOnNodesChange]);
const handleReactFlowNodesChange = useCallback((changes: NodeChange[]) => {
onNodesChange(changes.filter((change) => !("id" in change) || change.id !== BATCH_SELECTION_NODE_ID) as NodeChange<WorkflowNode>[]);
const flushPendingDragPositionChanges = useCallback(() => {
if (pendingDragPositionFrameRef.current !== null) {
cancelAnimationFrame(pendingDragPositionFrameRef.current);
pendingDragPositionFrameRef.current = null;
}
const pendingChanges = pendingDragPositionChangesRef.current;
if (pendingChanges.size === 0) return;
const changes = Array.from(pendingChanges.values());
pendingChanges.clear();
onNodesChange(changes);
}, [onNodesChange]);
const scheduleDragPositionChanges = useCallback((changes: NodeChange<WorkflowNode>[]) => {
const pendingChanges = pendingDragPositionChangesRef.current;
for (const change of changes) {
if (!("id" in change)) continue;
pendingChanges.set(change.id, change);
}
if (pendingDragPositionFrameRef.current !== null) return;
pendingDragPositionFrameRef.current = requestAnimationFrame(() => {
pendingDragPositionFrameRef.current = null;
const queuedChanges = Array.from(pendingChanges.values());
pendingChanges.clear();
if (queuedChanges.length > 0) {
onNodesChange(queuedChanges);
}
});
}, [onNodesChange]);
const handleReactFlowNodesChange = useCallback((changes: NodeChange[]) => {
const workflowChanges = changes.filter((change) => !("id" in change) || change.id !== BATCH_SELECTION_NODE_ID) as NodeChange<WorkflowNode>[];
const dragPositionChanges: NodeChange<WorkflowNode>[] = [];
const immediateChanges: NodeChange<WorkflowNode>[] = [];
for (const change of workflowChanges) {
if (change.type === "position" && (change as { dragging?: boolean }).dragging === true) {
dragPositionChanges.push(change);
} else {
immediateChanges.push(change);
}
}
if (immediateChanges.length > 0) {
flushPendingDragPositionChanges();
onNodesChange(immediateChanges);
}
if (dragPositionChanges.length > 0) {
scheduleDragPositionChanges(dragPositionChanges);
}
}, [flushPendingDragPositionChanges, onNodesChange, scheduleDragPositionChanges]);
const addNodeWithOptionalGroup = useCallback((
type: NodeType,
position: { x: number; y: number },
@ -726,6 +782,11 @@ export function WorkflowCanvas() {
if (boxSelectionEndTimerRef.current) {
clearTimeout(boxSelectionEndTimerRef.current);
}
if (pendingDragPositionFrameRef.current !== null) {
cancelAnimationFrame(pendingDragPositionFrameRef.current);
pendingDragPositionFrameRef.current = null;
}
pendingDragPositionChangesRef.current.clear();
document.documentElement.classList.remove("box-selection-active");
document.documentElement.classList.remove("canvas-interacting");
document.documentElement.classList.remove("canvas-node-drag-active");
@ -3059,8 +3120,8 @@ export function WorkflowCanvas() {
/>
<div className="ml-1 flex h-[25px] w-24 items-center [&_.ant-slider]:!m-0">
<Slider
min={10}
max={400}
min={CANVAS_MIN_ZOOM_PERCENT}
max={CANVAS_MAX_ZOOM_PERCENT}
step={3}
value={zoomPercent}
onChange={handleZoomPercentChange}

Loading…
Cancel
Save