perf: 探索图减少卡顿(数据未变不重建 + 只渲染可见节点)
- graph-tab:轮询按签名判重,图数据无变化时跳过 setState,避免整图重建; 拖动不再被 20s 轮询打断 - ExplorationGraph:ReactFlow 加 onlyRenderVisibleElements,屏幕外节点不渲染
This commit is contained in:
1 parent
08cdac2362
commit
24a94cf8e5
2 files changed
+15
-2
No files matched your search
@@ -10,16 +10,28 @@ import type { Edge, TaskNode } from "@/lib/types";
|
|||||||
export function GraphTab({ taskId }: { taskId: string }) {
|
export function GraphTab({ taskId }: { taskId: string }) {
|
||||||
const [nodes, setNodes] = React.useState<TaskNode[]>([]);
|
const [nodes, setNodes] = React.useState<TaskNode[]>([]);
|
||||||
const [edges, setEdges] = React.useState<Edge[]>([]);
|
const [edges, setEdges] = React.useState<Edge[]>([]);
|
||||||
|
// 上一次图数据的签名:轮询拿到相同数据时跳过 setState,避免整图无谓重建(拖动时
|
||||||
|
// 才不会被 20s 轮询打断而顿挫)。只取影响渲染的字段。
|
||||||
|
const sigRef = React.useRef("");
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
sigRef.current = ""; // 换任务:强制下一次刷新
|
||||||
const load = () => {
|
const load = () => {
|
||||||
api
|
api
|
||||||
.explorationGraph(taskId)
|
.explorationGraph(taskId)
|
||||||
.then((g) => {
|
.then((g) => {
|
||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
setNodes(g.nodes ?? []);
|
const ns = g.nodes ?? [];
|
||||||
setEdges(g.edges ?? []);
|
const es = g.edges ?? [];
|
||||||
|
const sig = JSON.stringify([
|
||||||
|
ns.map((n) => [n.id, n.type, n.state, n.priority, n.payload]),
|
||||||
|
es.map((e) => [e.src, e.dst, e.rel]),
|
||||||
|
]);
|
||||||
|
if (sig === sigRef.current) return; // 无变化 → 不重建
|
||||||
|
sigRef.current = sig;
|
||||||
|
setNodes(ns);
|
||||||
|
setEdges(es);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
/* keep last good data */
|
/* keep last good data */
|
||||||
|
|||||||
@@ -444,6 +444,7 @@ function ExplorationGraphInner({
|
|||||||
fitView
|
fitView
|
||||||
fitViewOptions={{ padding: 0.2 }}
|
fitViewOptions={{ padding: 0.2 }}
|
||||||
proOptions={{ hideAttribution: true }}
|
proOptions={{ hideAttribution: true }}
|
||||||
|
onlyRenderVisibleElements
|
||||||
minZoom={0.1}
|
minZoom={0.1}
|
||||||
className="!bg-[#f0f2f7] dark:!bg-neutral-950"
|
className="!bg-[#f0f2f7] dark:!bg-neutral-950"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in new issue
Block a user