From e90c00c3b768475e80a2cf13b99239095b49e65f Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Fri, 28 Feb 2025 04:51:54 +0000 Subject: [PATCH] refactor(editor): perf optimization of flat data (#10494) The new code should be more efficient as it: - Avoids unnecessary iterations when objects aren't empty - Has clearer path management - Reduces redundant object traversals --- .../store/src/reactive/flat-native-y.ts | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/blocksuite/framework/store/src/reactive/flat-native-y.ts b/blocksuite/framework/store/src/reactive/flat-native-y.ts index be80d9823d..af19d3f7c3 100644 --- a/blocksuite/framework/store/src/reactive/flat-native-y.ts +++ b/blocksuite/framework/store/src/reactive/flat-native-y.ts @@ -318,20 +318,26 @@ export class ReactiveFlatYMap extends BaseReactiveYData< return; } this._updateWithYjsSkip(() => { - void keys.reduce((acc, key, index, arr) => { - if (index === arr.length - 1) { + void keys.reduce((acc, key, index) => { + if (index === keys.length - 1) { delete acc[key]; - let i = index - 1; let curr = acc; - while (i > 0) { - const parentPath = keys.slice(0, i); - const parentKey = keys[i]; - const parent = parentPath.reduce((acc, key) => { - return acc[key] as UnRecord; - }, proxy as UnRecord); + let parentKey = keys[index - 1]; + let parent = proxy as UnRecord; + let path = keys.slice(0, -2); + + for (let i = keys.length - 2; i > 0; i--) { + for (const pathKey of path) { + parent = parent[pathKey] as UnRecord; + } + if (!isEmptyObject(curr)) { + break; + } deleteEmptyObject(curr, parentKey, parent); curr = parent; - i--; + parentKey = keys[i - 1]; + path = path.slice(0, -1); + parent = proxy as UnRecord; } } return acc[key] as UnRecord; @@ -487,8 +493,12 @@ export class ReactiveFlatYMap extends BaseReactiveYData< }; } +function isEmptyObject(obj: UnRecord): boolean { + return Object.keys(obj).length === 0; +} + function deleteEmptyObject(obj: UnRecord, key: string, parent: UnRecord): void { - if (Object.keys(obj).length === 0) { + if (isEmptyObject(obj)) { delete parent[key]; } }