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
This commit is contained in:
Saul-Mirone
2025-02-28 04:51:54 +00:00
parent 1d865ad883
commit e90c00c3b7
@@ -318,20 +318,26 @@ export class ReactiveFlatYMap extends BaseReactiveYData<
return; return;
} }
this._updateWithYjsSkip(() => { this._updateWithYjsSkip(() => {
void keys.reduce((acc, key, index, arr) => { void keys.reduce((acc, key, index) => {
if (index === arr.length - 1) { if (index === keys.length - 1) {
delete acc[key]; delete acc[key];
let i = index - 1;
let curr = acc; let curr = acc;
while (i > 0) { let parentKey = keys[index - 1];
const parentPath = keys.slice(0, i); let parent = proxy as UnRecord;
const parentKey = keys[i]; let path = keys.slice(0, -2);
const parent = parentPath.reduce((acc, key) => {
return acc[key] as UnRecord; for (let i = keys.length - 2; i > 0; i--) {
}, proxy as UnRecord); for (const pathKey of path) {
parent = parent[pathKey] as UnRecord;
}
if (!isEmptyObject(curr)) {
break;
}
deleteEmptyObject(curr, parentKey, parent); deleteEmptyObject(curr, parentKey, parent);
curr = parent; curr = parent;
i--; parentKey = keys[i - 1];
path = path.slice(0, -1);
parent = proxy as UnRecord;
} }
} }
return acc[key] 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 { function deleteEmptyObject(obj: UnRecord, key: string, parent: UnRecord): void {
if (Object.keys(obj).length === 0) { if (isEmptyObject(obj)) {
delete parent[key]; delete parent[key];
} }
} }