perf: 优化智能体与工作流幕布渲染性能
- 分阶段加载智能体配置并按需缓存 MCP 工具 - 合并画布状态更新与节点尺寸监听,启用大图可视区域渲染和静态连线 - 隔离 Tinyflow Store 实例并补充数据同步与回归测试
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import type { Node } from '@xyflow/svelte';
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
createTinyflowNodeNormalizer,
|
||||
DEFAULT_NODE_DRAG_HANDLE,
|
||||
} from './nodeInteraction';
|
||||
|
||||
function createNode(patch: Partial<Node> = {}): Node {
|
||||
return {
|
||||
data: {},
|
||||
id: 'node-1',
|
||||
position: { x: 0, y: 0 },
|
||||
type: 'customNode',
|
||||
...patch,
|
||||
};
|
||||
}
|
||||
|
||||
describe('createTinyflowNodeNormalizer', () => {
|
||||
it('节点已经规范化时保留引用', () => {
|
||||
const normalizer = createTinyflowNodeNormalizer();
|
||||
const node = createNode({ dragHandle: DEFAULT_NODE_DRAG_HANDLE });
|
||||
|
||||
expect(normalizer(node)).toBe(node);
|
||||
});
|
||||
|
||||
it('需要补齐交互属性时采用写时复制且不修改输入', () => {
|
||||
const normalizer = createTinyflowNodeNormalizer();
|
||||
const node = createNode();
|
||||
|
||||
const normalized = normalizer(node);
|
||||
|
||||
expect(normalized).not.toBe(node);
|
||||
expect(normalized.dragHandle).toBe(DEFAULT_NODE_DRAG_HANDLE);
|
||||
expect(node.dragHandle).toBeUndefined();
|
||||
});
|
||||
|
||||
it('只读节点已经包含限制属性时保留引用', () => {
|
||||
const normalizer = createTinyflowNodeNormalizer({ readonly: true } as any);
|
||||
const node = createNode({
|
||||
connectable: false,
|
||||
draggable: false,
|
||||
selectable: false,
|
||||
});
|
||||
|
||||
expect(normalizer(node)).toBe(node);
|
||||
});
|
||||
});
|
||||
@@ -25,33 +25,45 @@ export function createTinyflowNodeNormalizer(
|
||||
const elementsSelectable = options?.elementsSelectable ?? !readonly;
|
||||
|
||||
return (node) => {
|
||||
const nextNode = { ...node };
|
||||
let nextNode = node;
|
||||
const mutableNode = () => {
|
||||
if (nextNode === node) {
|
||||
nextNode = { ...node };
|
||||
}
|
||||
return nextNode;
|
||||
};
|
||||
|
||||
if (nodesDraggable) {
|
||||
if (nextNode.draggable === false) {
|
||||
delete nextNode.draggable;
|
||||
delete mutableNode().draggable;
|
||||
}
|
||||
if (shouldUseDefaultDragHandle(nextNode, options?.customNodes)) {
|
||||
nextNode.dragHandle = DEFAULT_NODE_DRAG_HANDLE;
|
||||
mutableNode().dragHandle = DEFAULT_NODE_DRAG_HANDLE;
|
||||
}
|
||||
} else {
|
||||
nextNode.draggable = false;
|
||||
if (nextNode.draggable !== false) {
|
||||
mutableNode().draggable = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodesConnectable) {
|
||||
if (nextNode.connectable === false) {
|
||||
delete nextNode.connectable;
|
||||
delete mutableNode().connectable;
|
||||
}
|
||||
} else {
|
||||
nextNode.connectable = false;
|
||||
if (nextNode.connectable !== false) {
|
||||
mutableNode().connectable = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (elementsSelectable) {
|
||||
if (nextNode.selectable === false) {
|
||||
delete nextNode.selectable;
|
||||
delete mutableNode().selectable;
|
||||
}
|
||||
} else {
|
||||
nextNode.selectable = false;
|
||||
if (nextNode.selectable !== false) {
|
||||
mutableNode().selectable = false;
|
||||
}
|
||||
}
|
||||
|
||||
return nextNode;
|
||||
|
||||
Reference in New Issue
Block a user