Skip to content

Commit 77dc507

Browse files
authored
tree: add fast path for children updates in compressedObjectTreeModel (microsoft#186804)
I noticed in testing that more things were getting rerendered than they should have been. This adds a fast path so that, if the elements in a compressed node don't change when its children are updated, we only update the children instead of replacing the entire node from the parent collection.
1 parent de68ea3 commit 77dc507

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
77
import { IIndexTreeModelSpliceOptions, IList } from 'vs/base/browser/ui/tree/indexTreeModel';
88
import { IObjectTreeModel, IObjectTreeModelOptions, IObjectTreeModelSetChildrenOptions, ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
99
import { ICollapseStateChangeEvent, IObjectTreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree';
10+
import { equals } from 'vs/base/common/arrays';
1011
import { Event } from 'vs/base/common/event';
1112
import { Iterable } from 'vs/base/common/iterator';
1213

@@ -170,6 +171,16 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
170171
const splicedElement = splice(decompressedElement, element, children);
171172
const recompressedElement = (this.enabled ? compress : noCompress)(splicedElement);
172173

174+
// If the recompressed node is identical to the original, just set its children.
175+
// Saves work and churn diffing the parent element.
176+
const elementComparator = options.diffIdentityProvider
177+
? ((a: T, b: T) => options.diffIdentityProvider!.getId(a) === options.diffIdentityProvider!.getId(b))
178+
: undefined;
179+
if (equals(recompressedElement.element.elements, node.element.elements, elementComparator)) {
180+
this._setChildren(compressedNode, recompressedElement.children || Iterable.empty(), { diffIdentityProvider, diffDepth: 1 });
181+
return;
182+
}
183+
173184
const parentChildren = parent.children
174185
.map(child => child === node ? recompressedElement : child);
175186

0 commit comments

Comments
 (0)