提交 387dc226 编写于 作者: R Rob Lourens

Settings editor - load settings in pages for much better perf #56296

上级 8cc5c650
......@@ -673,7 +673,7 @@ export class TreeView extends HeightMap {
}
public getLastVisibleElement(): any {
const item = this.itemAtIndex(this.indexAt(this.lastRenderTop + this.lastRenderHeight));
const item = this.itemAtIndex(this.indexAt(this.lastRenderTop + this.lastRenderHeight - 1));
return item && item.model.getElement();
}
......
......@@ -39,8 +39,8 @@ import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/sugge
import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor';
import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout';
import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree } from 'vs/workbench/parts/preferences/browser/settingsTree';
import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, countSettingGroupChildrenWithPredicate } from 'vs/workbench/parts/preferences/browser/settingsTreeModels';
import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree, SimplePagedDataSource, SettingsDataSource } from 'vs/workbench/parts/preferences/browser/settingsTree';
import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, countSettingGroupChildrenWithPredicate, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels';
import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree';
import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences';
import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService';
......@@ -71,6 +71,7 @@ export class SettingsEditor2 extends BaseEditor {
private settingsTreeContainer: HTMLElement;
private settingsTree: Tree;
private settingsTreeRenderer: SettingsRenderer;
private settingsTreeDataSource: SimplePagedDataSource;
private tocTreeModel: TOCTreeModel;
private settingsTreeModel: SettingsTreeModel;
private noResultsMessage: HTMLElement;
......@@ -426,14 +427,19 @@ export class SettingsEditor2 extends BaseEditor {
}));
this._register(this.tocTree.onDidChangeFocus(e => {
const element = e.focus;
const element: SettingsTreeGroupElement = e.focus;
if (this.searchResultModel) {
this.viewState.filterToCategory = element;
this.renderTree();
}
if (element && (!e.payload || !e.payload.fromScroll)) {
this.settingsTree.reveal(element, 0);
let refreshP = TPromise.wrap(null);
if (this.settingsTreeDataSource.pageTo(element.index)) {
refreshP = this.renderTree();
}
refreshP.then(() => this.settingsTree.reveal(element, 0));
}
}));
......@@ -463,11 +469,15 @@ export class SettingsEditor2 extends BaseEditor {
this.settingsTree.reveal(element);
}));
this.settingsTreeDataSource = this.instantiationService.createInstance(SimplePagedDataSource,
this.instantiationService.createInstance(SettingsDataSource, this.viewState));
this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree,
this.settingsTreeContainer,
this.viewState,
{
renderer: this.settingsTreeRenderer
renderer: this.settingsTreeRenderer,
dataSource: this.settingsTreeDataSource
}));
this.settingsTree.getHTMLElement().attributes.removeNamedItem('tabindex');
......@@ -516,6 +526,8 @@ export class SettingsEditor2 extends BaseEditor {
return;
}
this.updateTreePagingByScroll();
const elementToSync = this.settingsTree.getFirstVisibleElement();
const element = elementToSync instanceof SettingsTreeSettingElement ? elementToSync.parent :
elementToSync instanceof SettingsTreeGroupElement ? elementToSync :
......@@ -536,6 +548,13 @@ export class SettingsEditor2 extends BaseEditor {
}
}
private updateTreePagingByScroll(): void {
const lastVisibleElement = this.settingsTree.getLastVisibleElement();
if (lastVisibleElement && this.settingsTreeDataSource.pageTo(lastVisibleElement.index)) {
this.renderTree();
}
}
private updateChangedSetting(key: string, value: any): TPromise<void> {
// ConfigurationService displays the error if this fails.
// Force a render afterwards because onDidConfigurationUpdate doesn't fire if the update doesn't result in an effective setting value change
......
......@@ -39,7 +39,7 @@ import { editorBackground, errorForeground, focusBorder, foreground, inputValida
import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout';
import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement, settingKeyToDisplayFormat } from 'vs/workbench/parts/preferences/browser/settingsTreeModels';
import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, settingKeyToDisplayFormat, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels';
import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectListBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets';
import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences';
......@@ -206,6 +206,58 @@ export class SettingsDataSource implements IDataSource {
}
}
export class SimplePagedDataSource implements IDataSource {
private static readonly SETTINGS_PER_PAGE = 30;
private loadedToIndex: number;
constructor(private realDataSource: IDataSource) {
this.loadedToIndex = SimplePagedDataSource.SETTINGS_PER_PAGE * 2;
}
pageTo(index: number): boolean {
if (index > this.loadedToIndex - SimplePagedDataSource.SETTINGS_PER_PAGE) {
this.loadedToIndex = (Math.ceil(index / SimplePagedDataSource.SETTINGS_PER_PAGE) + 1) * SimplePagedDataSource.SETTINGS_PER_PAGE;
return true;
} else {
return false;
}
}
getId(tree: ITree, element: any): string {
return this.realDataSource.getId(tree, element);
}
hasChildren(tree: ITree, element: any): boolean {
return this.realDataSource.hasChildren(tree, element);
}
getChildren(tree: ITree, element: SettingsTreeGroupElement): TPromise<any> {
return this.realDataSource.getChildren(tree, element).then(realChildren => {
return this._getChildren(realChildren);
});
}
_getChildren(realChildren: SettingsTreeElement[]): any[] {
const lastChild = realChildren[realChildren.length - 1];
if (lastChild && lastChild.index > this.loadedToIndex) {
return realChildren.filter(child => {
return child.index < this.loadedToIndex;
});
} else {
return realChildren;
}
}
getParent(tree: ITree, element: any): TPromise<any> {
return this.realDataSource.getParent(tree, element);
}
shouldAutoexpand(tree: ITree, element: any): boolean {
return this.realDataSource.shouldAutoexpand(tree, element);
}
}
interface IDisposableTemplate {
toDispose: IDisposable[];
}
......@@ -1374,7 +1426,6 @@ export class SettingsTree extends NonExpandableOrSelectableTree {
const controller = instantiationService.createInstance(SettingsTreeController);
const fullConfiguration = <ITreeConfiguration>{
dataSource: instantiationService.createInstance(SettingsDataSource, viewState),
controller,
accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider),
filter: instantiationService.createInstance(SettingsTreeFilter, viewState),
......
......@@ -25,6 +25,11 @@ export interface ISettingsEditorViewState {
export abstract class SettingsTreeElement {
id: string;
parent: SettingsTreeGroupElement;
/**
* Index assigned in display order, used for paging.
*/
index: number;
}
export class SettingsTreeGroupElement extends SettingsTreeElement {
......@@ -42,8 +47,8 @@ export class SettingsTreeNewExtensionsElement extends SettingsTreeElement {
export class SettingsTreeSettingElement extends SettingsTreeElement {
setting: ISetting;
_displayCategory: string;
_displayLabel: string;
private _displayCategory: string;
private _displayLabel: string;
/**
* scopeValue || defaultValue, for rendering convenience.
......@@ -70,8 +75,9 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
description: string;
valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex' | 'nullable-integer' | 'nullable-number';
constructor(setting: ISetting, parent: SettingsTreeGroupElement, inspectResult: IInspectResult) {
constructor(setting: ISetting, parent: SettingsTreeGroupElement, index: number, inspectResult: IInspectResult) {
super();
this.index = index;
this.setting = setting;
this.parent = parent;
this.id = sanitizeId(parent.id + '_' + setting.key);
......@@ -193,7 +199,7 @@ export function countSettingGroupChildrenWithPredicate(tree: SettingsTreeGroupEl
export class SettingsTreeModel {
protected _root: SettingsTreeGroupElement;
private _treeElementsById = new Map<string, SettingsTreeElement>();
protected _treeElementsById = new Map<string, SettingsTreeElement>();
private _treeElementsBySettingName = new Map<string, SettingsTreeSettingElement[]>();
private _tocRoot: ITOCEntry;
......@@ -243,6 +249,8 @@ export class SettingsTreeModel {
private createSettingsTreeGroupElement(tocEntry: ITOCEntry, parent?: SettingsTreeGroupElement): SettingsTreeGroupElement {
const element = new SettingsTreeGroupElement();
const index = this._treeElementsById.size;
element.index = index;
element.id = tocEntry.id;
element.label = tocEntry.label;
element.parent = parent;
......@@ -273,8 +281,9 @@ export class SettingsTreeModel {
}
private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement {
const index = this._treeElementsById.size;
const inspectResult = inspectSetting(setting.key, this._viewState.settingsTarget, this._configurationService);
const element = new SettingsTreeSettingElement(setting, parent, inspectResult);
const element = new SettingsTreeSettingElement(setting, parent, index, inspectResult);
this._treeElementsById.set(element.id, element);
const nameElements = this._treeElementsBySettingName.get(setting.key) || [];
......@@ -449,8 +458,11 @@ export class SearchResultModel extends SettingsTreeModel {
if (this.newExtensionSearchResults && this.newExtensionSearchResults.filterMatches.length) {
const newExtElement = new SettingsTreeNewExtensionsElement();
newExtElement.index = this._treeElementsById.size;
newExtElement.parent = this._root;
newExtElement.id = 'newExtensions';
this._treeElementsById.set(newExtElement.id, newExtElement);
const resultExtensionIds = this.newExtensionSearchResults.filterMatches
.map(result => (<IExtensionSetting>result.setting))
.filter(setting => setting.extensionName && setting.extensionPublisher)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册