list view: request scrollable element on next animation frame

This commit is contained in:
Joao Moreno
2018-09-26 22:56:54 +02:00
parent 39238cb357
commit d2fd43d8a2
3 changed files with 30 additions and 9 deletions

View File

@@ -64,6 +64,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
private gesture: Gesture;
private rowsContainer: HTMLElement;
private scrollableElement: ScrollableElement;
private didRequestScrollableElementUpdate: boolean = false;
private splicing = false;
private dragAndDropScrollInterval: number;
private dragAndDropScrollTimeout: number;
@@ -198,7 +199,15 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
const scrollHeight = this.getContentHeight();
this.rowsContainer.style.height = `${scrollHeight}px`;
this.scrollableElement.setScrollDimensions({ scrollHeight });
if (!this.didRequestScrollableElementUpdate) {
DOM.scheduleAtNextAnimationFrame(() => {
this.scrollableElement.setScrollDimensions({ scrollHeight });
this.didRequestScrollableElementUpdate = false;
});
this.didRequestScrollableElementUpdate = true;
}
return deleted.map(i => i.element);
}

View File

@@ -174,6 +174,10 @@ export class Tree<T, TFilterData = void> implements IDisposable {
return this.model.splice(location, deleteCount, toInsert);
}
collapseAll(): void {
this.model.setCollapsedAll(true);
}
refilter(location?: number[]): void {
this.model.refilter(location);
}

View File

@@ -22,10 +22,19 @@
<body>
<input type="text" id="filter" />
<button id="collapseall">Collapse All</button>
<div id="container"></div>
<script src="/static/vs/loader.js"></script>
<script>
function perf(name, fn) {
performance.mark('before ' + name);
const start = performance.now();
fn();
console.log(name + ' took', performance.now() - start);
performance.mark('after ' + name);
}
require.config({ baseUrl: '/static' });
require(['vs/base/browser/ui/tree/tree', 'vs/base/browser/ui/tree/treeModel', 'vs/base/common/iterator'], ({ Tree }, { Visibility }, { iter }) => {
@@ -60,11 +69,7 @@
this.pattern = new RegExp(filter.value, 'i');
}
performance.mark('before refilter');
const start = performance.now();
tree.refilter();
console.log('refilter took', performance.now() - start);
performance.mark('after refilter');
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el) : true) ? Visibility.Visible : Visibility.Recurse;
@@ -75,7 +80,7 @@
function setModel(model) {
performance.mark('before splice');
const start = performance.now();
tree.splice([0], 0, model);
;
console.log('splice took', performance.now() - start);
performance.mark('after splice');
}
@@ -92,7 +97,8 @@
files.push({ element: `file #${i}`, children: errors });
}
setModel(files);
perf('splice', () => tree.splice([0], 0, files));
break;
}
default:
@@ -101,10 +107,12 @@
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
setModel([JSON.parse(this.responseText)]);
perf('splice', () => tree.splice([0], 0, [JSON.parse(this.responseText)]));
}
};
}
collapseall.onclick = () => tree.collapseAll();
});
</script>
</body>