优化编辑器状态相等性检查

用可提前退出的递归比较替代完整状态序列化\n减少每次编辑提交的无谓 JSON 字符串构造
This commit is contained in:
2026-09-03 12:00:36 +08:00
parent 37c465dbc3
commit b07c8a5e25
@@ -237,7 +237,30 @@ function cloneState(state: State): State {
}
function sameResource<T>(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<string, unknown>;
const rightRecord = right as Record<string, unknown>;
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({