mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
perf(devtools): prevent directive forest from building twice every time a node is selected in the directive explorer
This commit is contained in:
parent
1a00837b0c
commit
ca0910e59c
5 changed files with 40 additions and 15 deletions
|
|
@ -71,19 +71,21 @@ const getLatestComponentExplorerViewCallback = (messageBus: MessageBus<Events>)
|
|||
) => {
|
||||
// We want to force re-indexing of the component tree.
|
||||
// Pressing the refresh button means the user saw stuck UI.
|
||||
|
||||
initializeOrGetDirectiveForestHooks().indexForest();
|
||||
|
||||
if (!query) {
|
||||
messageBus.emit('latestComponentExplorerView', [
|
||||
{
|
||||
forest: prepareForestForSerialization(initializeOrGetDirectiveForestHooks().getDirectiveForest()),
|
||||
forest: prepareForestForSerialization(initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest()),
|
||||
},
|
||||
]);
|
||||
return;
|
||||
}
|
||||
messageBus.emit('latestComponentExplorerView', [
|
||||
{
|
||||
forest: prepareForestForSerialization(initializeOrGetDirectiveForestHooks().getDirectiveForest()),
|
||||
properties: getLatestComponentState(query),
|
||||
forest: prepareForestForSerialization(initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest()),
|
||||
properties: getLatestComponentState(query, initializeOrGetDirectiveForestHooks().getDirectiveForest()),
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
|
@ -100,7 +102,7 @@ const stopProfilingCallback = (messageBus: MessageBus<Events>) => () => {
|
|||
};
|
||||
|
||||
const selectedComponentCallback = (position: ElementPosition) => {
|
||||
const node = queryDirectiveForest(position, initializeOrGetDirectiveForestHooks().getDirectiveForest());
|
||||
const node = queryDirectiveForest(position, initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest());
|
||||
setConsoleReference({ node, position });
|
||||
};
|
||||
|
||||
|
|
@ -109,7 +111,10 @@ const getNestedPropertiesCallback = (messageBus: MessageBus<Events>) => (
|
|||
propPath: string[]
|
||||
) => {
|
||||
const emitEmpty = () => messageBus.emit('nestedProperties', [position, { props: {} }, propPath]);
|
||||
const node = queryDirectiveForest(position.element, initializeOrGetDirectiveForestHooks().getDirectiveForest());
|
||||
const node = queryDirectiveForest(
|
||||
position.element,
|
||||
initializeOrGetDirectiveForestHooks().getIndexedDirectiveForest()
|
||||
);
|
||||
if (!node) {
|
||||
return emitEmpty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,14 @@ export interface ComponentTreeNode extends DevToolsNode<DirectiveInstanceType, C
|
|||
children: ComponentTreeNode[];
|
||||
}
|
||||
|
||||
export const getLatestComponentState = (query: ComponentExplorerViewQuery): DirectivesProperties | undefined => {
|
||||
const node = queryDirectiveForest(query.selectedElement, buildDirectiveForest());
|
||||
export const getLatestComponentState = (
|
||||
query: ComponentExplorerViewQuery,
|
||||
directiveForest?: ComponentTreeNode[]
|
||||
): DirectivesProperties | undefined => {
|
||||
// if a directive forest is passed in we don't have to build the forest again.
|
||||
directiveForest = directiveForest ?? buildDirectiveForest();
|
||||
|
||||
const node = queryDirectiveForest(query.selectedElement, directiveForest);
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ const prepareInitialFrame = (source: string, duration: number) => {
|
|||
directives: [],
|
||||
};
|
||||
const directiveForestHooks = initializeOrGetDirectiveForestHooks();
|
||||
const directiveForest = directiveForestHooks.getDirectiveForest();
|
||||
const directiveForest = directiveForestHooks.getIndexedDirectiveForest();
|
||||
const traverse = (node: ComponentTreeNode, children = frame.directives) => {
|
||||
let position: ElementPosition | undefined;
|
||||
if (node.component) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ComponentTreeNode } from './../component-tree';
|
||||
import { ElementPosition, LifecycleProfile } from 'protocol';
|
||||
import { componentMetadata, runOutsideAngular } from '../utils';
|
||||
import { IdentityTracker, IndexedNode } from './identity-tracker';
|
||||
|
|
@ -109,7 +110,8 @@ export class DirectiveForestHooks {
|
|||
private _undoLifecyclePatch: (() => void)[] = [];
|
||||
private _lastChangeDetection = new Map<any, number>();
|
||||
private _tracker = new IdentityTracker();
|
||||
private _forest: IndexedNode[] = [];
|
||||
private _forest: ComponentTreeNode[] = [];
|
||||
private _indexedForest: IndexedNode[] = [];
|
||||
private _inChangeDetection = false;
|
||||
private _changeDetection$ = new Subject<void>();
|
||||
|
||||
|
|
@ -139,7 +141,11 @@ export class DirectiveForestHooks {
|
|||
return result;
|
||||
}
|
||||
|
||||
getDirectiveForest(): IndexedNode[] {
|
||||
getIndexedDirectiveForest(): IndexedNode[] {
|
||||
return this._indexedForest;
|
||||
}
|
||||
|
||||
getDirectiveForest(): ComponentTreeNode[] {
|
||||
return this._forest;
|
||||
}
|
||||
|
||||
|
|
@ -163,8 +169,9 @@ export class DirectiveForestHooks {
|
|||
}
|
||||
|
||||
indexForest(): void {
|
||||
const { newNodes, removedNodes, indexedForest } = this._tracker.index();
|
||||
this._forest = indexedForest;
|
||||
const { newNodes, removedNodes, indexedForest, directiveForest } = this._tracker.index();
|
||||
this._indexedForest = indexedForest;
|
||||
this._forest = directiveForest;
|
||||
newNodes.forEach((node) => {
|
||||
this._observeLifecycle(node.directive, node.isComponent);
|
||||
this._observeComponent(node.directive);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ComponentTreeNode } from './../component-tree';
|
||||
import { ElementPosition, DevToolsNode } from 'protocol';
|
||||
import { buildDirectiveForest, DirectiveInstanceType, ComponentInstanceType } from '../component-tree';
|
||||
import { Type } from '@angular/core';
|
||||
|
|
@ -31,8 +32,14 @@ export class IdentityTracker {
|
|||
return this._currentDirectiveId.has(dir);
|
||||
}
|
||||
|
||||
index(): { newNodes: NodeArray; removedNodes: NodeArray; indexedForest: IndexedNode[] } {
|
||||
const indexedForest = indexForest(buildDirectiveForest());
|
||||
index(): {
|
||||
newNodes: NodeArray;
|
||||
removedNodes: NodeArray;
|
||||
indexedForest: IndexedNode[];
|
||||
directiveForest: ComponentTreeNode[];
|
||||
} {
|
||||
const directiveForest = buildDirectiveForest();
|
||||
const indexedForest = indexForest(directiveForest);
|
||||
const newNodes: NodeArray = [];
|
||||
const removedNodes: NodeArray = [];
|
||||
const allNodes = new Set<any>();
|
||||
|
|
@ -46,7 +53,7 @@ export class IdentityTracker {
|
|||
// this._currentDirectivePosition.delete(dir);
|
||||
}
|
||||
});
|
||||
return { newNodes, removedNodes, indexedForest };
|
||||
return { newNodes, removedNodes, indexedForest, directiveForest };
|
||||
}
|
||||
|
||||
private _index(
|
||||
|
|
|
|||
Loading…
Reference in a new issue