Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js

Issue 2673733003: DevTools: Speed up timeline aggregated tree building. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
4 /** 5 /**
5 * @unrestricted 6 * @unrestricted
6 */ 7 */
7 Timeline.TimelineTreeView = class extends UI.VBox { 8 Timeline.TimelineTreeView = class extends UI.VBox {
8 constructor() { 9 constructor() {
9 super(); 10 super();
10 this.element.classList.add('timeline-tree-view'); 11 this.element.classList.add('timeline-tree-view');
11 } 12 }
12 13
13 /** 14 /**
14 * @param {!SDK.TracingModel.Event} event 15 * @param {!SDK.TracingModel.Event} event
15 * @return {string} 16 * @return {string}
16 */ 17 */
17 static eventNameForSorting(event) { 18 static eventNameForSorting(event) {
18 if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame) { 19 if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame) {
19 var data = event.args['data']; 20 var data = event.args['data'];
20 return data['functionName'] + '@' + (data['scriptId'] || data['url'] || '' ); 21 return `${data['functionName']}@${data['scriptId'] || data['url'] || ''}`;
caseq 2017/02/03 19:55:25 let's revert this
alph 2017/02/03 20:06:01 Done.
21 } 22 }
22 return event.name + ':@' + TimelineModel.TimelineProfileTree.eventURL(event) ; 23 return event.name + ':@' + TimelineModel.TimelineProfileTree.eventURL(event) ;
23 } 24 }
24 25
25 /** 26 /**
26 * @protected 27 * @protected
27 * @param {!TimelineModel.TimelineModel} model 28 * @param {!TimelineModel.TimelineModel} model
28 * @param {!Array<!TimelineModel.TimelineModelFilter>} filters 29 * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
29 */ 30 */
30 init(model, filters) { 31 init(model, filters) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 } 145 }
145 } 146 }
146 147
147 /** 148 /**
148 * @protected 149 * @protected
149 */ 150 */
150 refreshTree() { 151 refreshTree() {
151 this._linkifier.reset(); 152 this._linkifier.reset();
152 this._dataGrid.rootNode().removeChildren(); 153 this._dataGrid.rootNode().removeChildren();
153 var tree = this._buildTree(); 154 var tree = this._buildTree();
154 if (!tree.children) 155 var children = tree.children();
155 return;
156 var maxSelfTime = 0; 156 var maxSelfTime = 0;
157 var maxTotalTime = 0; 157 var maxTotalTime = 0;
158 for (var child of tree.children.values()) { 158 for (var child of children.values()) {
159 maxSelfTime = Math.max(maxSelfTime, child.selfTime); 159 maxSelfTime = Math.max(maxSelfTime, child.selfTime);
160 maxTotalTime = Math.max(maxTotalTime, child.totalTime); 160 maxTotalTime = Math.max(maxTotalTime, child.totalTime);
161 } 161 }
162 for (var child of tree.children.values()) { 162 for (var child of children.values()) {
163 // Exclude the idle time off the total calculation. 163 // Exclude the idle time off the total calculation.
164 var gridNode = new Timeline.TimelineTreeView.TreeGridNode(child, tree.tota lTime, maxSelfTime, maxTotalTime, this); 164 var gridNode = new Timeline.TimelineTreeView.TreeGridNode(child, tree.tota lTime, maxSelfTime, maxTotalTime, this);
165 this._dataGrid.insertChild(gridNode); 165 this._dataGrid.insertChild(gridNode);
166 } 166 }
167 this._sortingChanged(); 167 this._sortingChanged();
168 this._updateDetailsForSelection(); 168 this._updateDetailsForSelection();
169 } 169 }
170 170
171 /** 171 /**
172 * @return {!TimelineModel.TimelineProfileTree.Node} 172 * @return {!TimelineModel.TimelineProfileTree.Node}
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 /** 308 /**
309 * @param {!TimelineModel.TimelineProfileTree.Node} treeNode 309 * @param {!TimelineModel.TimelineProfileTree.Node} treeNode
310 * @protected 310 * @protected
311 * @return {?Timeline.TimelineTreeView.GridNode} 311 * @return {?Timeline.TimelineTreeView.GridNode}
312 */ 312 */
313 dataGridNodeForTreeNode(treeNode) { 313 dataGridNodeForTreeNode(treeNode) {
314 return treeNode[Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol] || n ull; 314 return treeNode[Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol] || n ull;
315 } 315 }
316 }; 316 };
317 317
318
319 /** 318 /**
320 * @unrestricted 319 * @unrestricted
321 */ 320 */
322 Timeline.TimelineTreeView.GridNode = class extends DataGrid.SortableDataGridNode { 321 Timeline.TimelineTreeView.GridNode = class extends DataGrid.SortableDataGridNode {
323 /** 322 /**
324 * @param {!TimelineModel.TimelineProfileTree.Node} profileNode 323 * @param {!TimelineModel.TimelineProfileTree.Node} profileNode
325 * @param {number} grandTotalTime 324 * @param {number} grandTotalTime
326 * @param {number} maxSelfTime 325 * @param {number} maxSelfTime
327 * @param {number} maxTotalTime 326 * @param {number} maxTotalTime
328 * @param {!Timeline.TimelineTreeView} treeView 327 * @param {!Timeline.TimelineTreeView} treeView
329 */ 328 */
330 constructor(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView) { 329 constructor(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView) {
331 super(null, false); 330 super(null, false);
332
333 this._populated = false; 331 this._populated = false;
334 this._profileNode = profileNode; 332 this._profileNode = profileNode;
335 this._treeView = treeView; 333 this._treeView = treeView;
336 this._grandTotalTime = grandTotalTime; 334 this._grandTotalTime = grandTotalTime;
337 this._maxSelfTime = maxSelfTime; 335 this._maxSelfTime = maxSelfTime;
338 this._maxTotalTime = maxTotalTime; 336 this._maxTotalTime = maxTotalTime;
339 } 337 }
340 338
341 /** 339 /**
342 * @override 340 * @override
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 Timeline.TimelineTreeView.TreeGridNode = class extends Timeline.TimelineTreeView .GridNode { 429 Timeline.TimelineTreeView.TreeGridNode = class extends Timeline.TimelineTreeView .GridNode {
432 /** 430 /**
433 * @param {!TimelineModel.TimelineProfileTree.Node} profileNode 431 * @param {!TimelineModel.TimelineProfileTree.Node} profileNode
434 * @param {number} grandTotalTime 432 * @param {number} grandTotalTime
435 * @param {number} maxSelfTime 433 * @param {number} maxSelfTime
436 * @param {number} maxTotalTime 434 * @param {number} maxTotalTime
437 * @param {!Timeline.TimelineTreeView} treeView 435 * @param {!Timeline.TimelineTreeView} treeView
438 */ 436 */
439 constructor(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView) { 437 constructor(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView) {
440 super(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView); 438 super(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView);
441 this.setHasChildren(this._profileNode.children ? this._profileNode.children. size > 0 : false); 439 this.setHasChildren(this._profileNode.hasChildren());
442 profileNode[Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol] = this; 440 profileNode[Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol] = this;
443 } 441 }
444 442
445 /** 443 /**
446 * @override 444 * @override
447 */ 445 */
448 populate() { 446 populate() {
449 if (this._populated) 447 if (this._populated)
450 return; 448 return;
451 this._populated = true; 449 this._populated = true;
452 if (!this._profileNode.children) 450 if (!this._profileNode.children)
453 return; 451 return;
454 for (var node of this._profileNode.children.values()) { 452 for (var node of this._profileNode.children().values()) {
455 var gridNode = new Timeline.TimelineTreeView.TreeGridNode( 453 var gridNode = new Timeline.TimelineTreeView.TreeGridNode(
456 node, this._grandTotalTime, this._maxSelfTime, this._maxTotalTime, thi s._treeView); 454 node, this._grandTotalTime, this._maxSelfTime, this._maxTotalTime, thi s._treeView);
457 this.insertChildOrdered(gridNode); 455 this.insertChildOrdered(gridNode);
458 } 456 }
459 } 457 }
460 }; 458 };
461 459
462 Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol = Symbol('treeGridNode'); 460 Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol = Symbol('treeGridNode');
463 461
464 /** 462 /**
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 this._executionContextNamesByOrigin.set(context.origin, context.name); 501 this._executionContextNamesByOrigin.set(context.origin, context.name);
504 } 502 }
505 } 503 }
506 504
507 /** 505 /**
508 * @param {!TimelineModel.TimelineProfileTree.Node} node 506 * @param {!TimelineModel.TimelineProfileTree.Node} node
509 * @return {!{name: string, color: string}} 507 * @return {!{name: string, color: string}}
510 */ 508 */
511 _displayInfoForGroupNode(node) { 509 _displayInfoForGroupNode(node) {
512 var categories = Timeline.TimelineUIUtils.categories(); 510 var categories = Timeline.TimelineUIUtils.categories();
513 var color = node.id ? Timeline.TimelineUIUtils.eventColor(node.event) : cate gories['other'].color; 511 var color = node.id ? Timeline.TimelineUIUtils.eventColor(/** @type {!SDK.Tr acingModel.Event} */ (node.event)) :
512 categories['other'].color;
514 513
515 switch (this._groupBySetting.get()) { 514 switch (this._groupBySetting.get()) {
516 case Timeline.AggregatedTimelineTreeView.GroupBy.Category: 515 case Timeline.AggregatedTimelineTreeView.GroupBy.Category:
517 var category = categories[node.id] || categories['other']; 516 var category = categories[node.id] || categories['other'];
518 return {name: category.title, color: category.color}; 517 return {name: category.title, color: category.color};
519 518
520 case Timeline.AggregatedTimelineTreeView.GroupBy.Domain: 519 case Timeline.AggregatedTimelineTreeView.GroupBy.Domain:
521 case Timeline.AggregatedTimelineTreeView.GroupBy.Subdomain: 520 case Timeline.AggregatedTimelineTreeView.GroupBy.Subdomain:
522 var name = node.id; 521 var name = node.id;
523 if (Timeline.AggregatedTimelineTreeView._isExtensionInternalURL(name)) 522 if (Timeline.AggregatedTimelineTreeView._isExtensionInternalURL(name))
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 * @param {!TimelineModel.TimelineProfileTree.Node} treeNode 586 * @param {!TimelineModel.TimelineProfileTree.Node} treeNode
588 * @return {!Array<!TimelineModel.TimelineProfileTree.Node>} 587 * @return {!Array<!TimelineModel.TimelineProfileTree.Node>}
589 */ 588 */
590 _buildHeaviestStack(treeNode) { 589 _buildHeaviestStack(treeNode) {
591 console.assert(!!treeNode.parent, 'Attempt to build stack for tree root'); 590 console.assert(!!treeNode.parent, 'Attempt to build stack for tree root');
592 var result = []; 591 var result = [];
593 // Do not add root to the stack, as it's the tree itself. 592 // Do not add root to the stack, as it's the tree itself.
594 for (var node = treeNode; node && node.parent; node = node.parent) 593 for (var node = treeNode; node && node.parent; node = node.parent)
595 result.push(node); 594 result.push(node);
596 result = result.reverse(); 595 result = result.reverse();
597 for (node = treeNode; node && node.children && node.children.size;) { 596 for (node = treeNode; node && node.children() && node.children().size;) {
598 var children = Array.from(node.children.values()); 597 var children = Array.from(node.children().values());
599 node = children.reduce((a, b) => a.totalTime > b.totalTime ? a : b); 598 node = children.reduce((a, b) => a.totalTime > b.totalTime ? a : b);
600 result.push(node); 599 result.push(node);
601 } 600 }
602 return result; 601 return result;
603 } 602 }
604 603
605 /** 604 /**
606 * @override 605 * @override
607 * @return {boolean} 606 * @return {boolean}
608 */ 607 */
(...skipping 19 matching lines...) Expand all
628 */ 627 */
629 _showDetailsForNode(node) { 628 _showDetailsForNode(node) {
630 var stack = this._buildHeaviestStack(node); 629 var stack = this._buildHeaviestStack(node);
631 this._stackView.setStack(stack, node); 630 this._stackView.setStack(stack, node);
632 this._stackView.show(this._detailsView.element); 631 this._stackView.show(this._detailsView.element);
633 return true; 632 return true;
634 } 633 }
635 634
636 /** 635 /**
637 * @param {!Timeline.AggregatedTimelineTreeView.GroupBy} groupBy 636 * @param {!Timeline.AggregatedTimelineTreeView.GroupBy} groupBy
638 * @return {function(!SDK.TracingModel.Event):string} 637 * @return {function(!SDK.TracingModel.Event):(string|symbol)}
639 */ 638 */
640 _groupingFunction(groupBy) { 639 _groupingFunction(groupBy) {
641 /** 640 /**
642 * @param {!SDK.TracingModel.Event} event 641 * @param {!SDK.TracingModel.Event} event
643 * @return {string} 642 * @return {string}
644 */ 643 */
645 function groupByURL(event) { 644 function groupByURL(event) {
646 return TimelineModel.TimelineProfileTree.eventURL(event) || ''; 645 return TimelineModel.TimelineProfileTree.eventURL(event) || '';
647 } 646 }
648 647
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 constructor(model, filters) { 775 constructor(model, filters) {
777 super(model, filters); 776 super(model, filters);
778 this._dataGrid.markColumnAsSortedBy('self', DataGrid.DataGrid.Order.Descendi ng); 777 this._dataGrid.markColumnAsSortedBy('self', DataGrid.DataGrid.Order.Descendi ng);
779 } 778 }
780 779
781 /** 780 /**
782 * @override 781 * @override
783 * @return {!TimelineModel.TimelineProfileTree.Node} 782 * @return {!TimelineModel.TimelineProfileTree.Node}
784 */ 783 */
785 _buildTree() { 784 _buildTree() {
786 var topDown = this.buildTopDownTree(this._groupingFunction(this._groupBySett ing.get())); 785 var tree = new TimelineModel.TimelineProfileTree(
787 return TimelineModel.TimelineProfileTree.buildBottomUp(topDown); 786 this._model.mainThreadEvents(), this._filters, this._startTime, this._en dTime,
787 this._groupingFunction(this._groupBySetting.get()));
788 return tree.bottomUpTreeRoot();
788 } 789 }
789 }; 790 };
790 791
791 /** 792 /**
792 * @unrestricted 793 * @unrestricted
793 */ 794 */
794 Timeline.TimelineStackView = class extends UI.VBox { 795 Timeline.TimelineStackView = class extends UI.VBox {
795 constructor(treeView) { 796 constructor(treeView) {
796 super(); 797 super();
797 var header = this.element.createChild('div', 'timeline-stack-view-header'); 798 var header = this.element.createChild('div', 'timeline-stack-view-header');
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 836
836 _onSelectionChanged() { 837 _onSelectionChanged() {
837 this.dispatchEventToListeners(Timeline.TimelineStackView.Events.SelectionCha nged); 838 this.dispatchEventToListeners(Timeline.TimelineStackView.Events.SelectionCha nged);
838 } 839 }
839 }; 840 };
840 841
841 /** @enum {symbol} */ 842 /** @enum {symbol} */
842 Timeline.TimelineStackView.Events = { 843 Timeline.TimelineStackView.Events = {
843 SelectionChanged: Symbol('SelectionChanged') 844 SelectionChanged: Symbol('SelectionChanged')
844 }; 845 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698