From b07c8a5e2593d9ee4b317fc34083c33de4056ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 3 Sep 2026 12:00:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=9B=B8=E7=AD=89=E6=80=A7=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用可提前退出的递归比较替代完整状态序列化\n减少每次编辑提交的无谓 JSON 字符串构造 --- .../features/ui-editor/useUiEditorState.ts | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts index 13ffa45e8..36c49730b 100644 --- a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts +++ b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts @@ -237,7 +237,30 @@ function cloneState(state: State): State { } function sameResource(left: T, right: T): boolean { - return JSON.stringify(left) === JSON.stringify(right); + if (Object.is(left, right)) return true; + if ( + typeof left !== 'object' || + left === null || + typeof right !== 'object' || + right === null + ) { + return false; + } + if (Array.isArray(left) || Array.isArray(right)) { + if (!Array.isArray(left) || !Array.isArray(right)) return false; + if (left.length !== right.length) return false; + return left.every((value, index) => sameResource(value, right[index])); + } + const leftRecord = left as Record; + const rightRecord = right as Record; + const leftKeys = Object.keys(leftRecord); + const rightKeys = Object.keys(rightRecord); + if (leftKeys.length !== rightKeys.length) return false; + return leftKeys.every( + (key) => + Object.prototype.hasOwnProperty.call(rightRecord, key) && + sameResource(leftRecord[key], rightRecord[key]), + ); } function visitComponents(nodes: Node[], visit: (component: Component) => void) { @@ -540,7 +563,7 @@ export function useUiEditorState(initialState: State = EMPTY_UI_EDITOR_STATE) { const commit = useCallback( (nextState: State) => { const current = stateRef.current; - if (JSON.stringify(current) === JSON.stringify(nextState)) return false; + if (sameResource(current, nextState)) return false; if (transactionRef.current === null) { undoStackRef.current.push({ before: cloneState(current), @@ -576,7 +599,7 @@ export function useUiEditorState(initialState: State = EMPTY_UI_EDITOR_STATE) { if (transaction === null) return; transactionRef.current = null; const current = stateRef.current; - if (JSON.stringify(transaction.before) === JSON.stringify(current)) { + if (sameResource(transaction.before, current)) { return; } undoStackRef.current.push({