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

Unified Diff: third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineProfileTree.js

Issue 2473283003: DevTools: add per-frame grouping into aggregated timeline details (Closed)
Patch Set: rebased Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineProfileTree.js
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineProfileTree.js b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineProfileTree.js
index 09c8076ef539a516fc8e4b19e667c101894d9f0e..9e7879dbe48c7d1ee5bb50feeece26e812787476 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineProfileTree.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineProfileTree.js
@@ -20,6 +20,9 @@ WebInspector.TimelineProfileTree.Node = class {
this.children;
/** @type {?WebInspector.TimelineProfileTree.Node} */
this.parent;
+
+ /** @type {string} */
+ this._groupId = '';
this._isGroupNode = false;
}
@@ -36,26 +39,32 @@ WebInspector.TimelineProfileTree.Node = class {
* @param {!Array<!WebInspector.TimelineModel.Filter>} filters
* @param {number} startTime
* @param {number} endTime
- * @param {function(!WebInspector.TracingModel.Event):(string|symbol)=} eventIdCallback
+ * @param {function(!WebInspector.TracingModel.Event, string):string=} eventGroupIdCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
-WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startTime, endTime, eventIdCallback) {
+WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startTime, endTime, eventGroupIdCallback) {
// Temporarily deposit a big enough value that exceeds the max recording time.
var /** @const */ initialTime = 1e7;
var root = new WebInspector.TimelineProfileTree.Node();
root.totalTime = initialTime;
root.selfTime = initialTime;
root.children = /** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */ (new Map());
+ var pageFrameIdStack = [];
var parent = root;
/**
* @param {!WebInspector.TracingModel.Event} e
*/
function onStartEvent(e) {
+ var pageFrameId = WebInspector.TimelineModel.eventFrameId(e) || pageFrameIdStack.peekLast();
+ pageFrameIdStack.push(pageFrameId);
if (!WebInspector.TimelineModel.isVisible(filters, e))
return;
var time = e.endTime ? Math.min(endTime, e.endTime) - Math.max(startTime, e.startTime) : 0;
- var id = eventIdCallback ? eventIdCallback(e) : Symbol('uniqueEventId');
+ var groupId = eventGroupIdCallback ? eventGroupIdCallback(e, pageFrameId) : Symbol('uniqueGroupId');
+ var id = eventGroupIdCallback ? WebInspector.TimelineProfileTree._eventId(e) : Symbol('uniqueEventId');
+ if (typeof groupId === 'string' && typeof id === 'string')
+ id += '/' + groupId;
if (!parent.children)
parent.children = /** @type {!Map<string,!WebInspector.TimelineProfileTree.Node>} */ (new Map());
var node = parent.children.get(id);
@@ -69,6 +78,7 @@ WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startT
node.parent = parent;
node.id = id;
node.event = e;
+ node._groupId = groupId;
parent.children.set(id, node);
}
parent.selfTime -= time;
@@ -84,12 +94,13 @@ WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startT
* @param {!WebInspector.TracingModel.Event} e
*/
function onEndEvent(e) {
+ pageFrameIdStack.pop();
if (!WebInspector.TimelineModel.isVisible(filters, e))
return;
parent = parent.parent;
}
- var instantEventCallback = eventIdCallback ? undefined : onStartEvent; // Ignore instant events when aggregating.
+ var instantEventCallback = eventGroupIdCallback ? undefined : onStartEvent; // Ignore instant events when aggregating.
WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, instantEventCallback, startTime, endTime);
root.totalTime -= root.selfTime;
root.selfTime = 0;
@@ -98,11 +109,11 @@ WebInspector.TimelineProfileTree.buildTopDown = function(events, filters, startT
/**
* @param {!WebInspector.TimelineProfileTree.Node} topDownTree
- * @param {?function(!WebInspector.TimelineProfileTree.Node):!WebInspector.TimelineProfileTree.Node=} groupingCallback
* @return {!WebInspector.TimelineProfileTree.Node}
*/
-WebInspector.TimelineProfileTree.buildBottomUp = function(topDownTree, groupingCallback) {
+WebInspector.TimelineProfileTree.buildBottomUp = function(topDownTree) {
var buRoot = new WebInspector.TimelineProfileTree.Node();
+ var aggregator = new WebInspector.TimelineAggregator();
buRoot.selfTime = 0;
buRoot.totalTime = 0;
/** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */
@@ -116,8 +127,8 @@ WebInspector.TimelineProfileTree.buildBottomUp = function(topDownTree, groupingC
* @param {!WebInspector.TimelineProfileTree.Node} tdNode
*/
function processNode(tdNode) {
- var buParent = groupingCallback && groupingCallback(tdNode) || buRoot;
- if (buParent !== buRoot) {
+ var buParent = typeof tdNode._groupId === 'string' ? aggregator.groupNodeForId(tdNode._groupId, tdNode.event) : buRoot;
+ if (buParent !== buRoot && !buParent.parent) {
buRoot.children.set(buParent.id, buParent);
buParent.parent = buRoot;
}
@@ -206,60 +217,34 @@ WebInspector.TimelineProfileTree.eventStackFrame = function(event) {
};
/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @return {string}
+ */
+WebInspector.TimelineProfileTree._eventId = function(event) {
+ if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) {
+ var data = event.args['data'];
+ return 'f:' + data['functionName'] + '@' + (data['scriptId'] || data['url'] || '');
+ }
+ return event.name;
+};
+
+
+/**
* @unrestricted
*/
WebInspector.TimelineAggregator = class {
- /**
- * @param {function(!WebInspector.TracingModel.Event):string} titleMapper
- * @param {function(!WebInspector.TracingModel.Event):string} categoryMapper
- */
- constructor(titleMapper, categoryMapper) {
- this._titleMapper = titleMapper;
- this._categoryMapper = categoryMapper;
+ constructor() {
/** @type {!Map<string, !WebInspector.TimelineProfileTree.Node>} */
this._groupNodes = new Map();
}
/**
- * @param {!WebInspector.TracingModel.Event} event
- * @return {string}
- */
- static eventId(event) {
- if (event.name === WebInspector.TimelineModel.RecordType.JSFrame) {
- var data = event.args['data'];
- return 'f:' + data['functionName'] + '@' + (data['scriptId'] || data['url'] || '');
- }
- return event.name + ':@' + WebInspector.TimelineProfileTree.eventURL(event);
- }
-
- /**
- * @param {string} url
- * @return {boolean}
- */
- static isExtensionInternalURL(url) {
- return url.startsWith(WebInspector.TimelineAggregator._extensionInternalPrefix);
- }
-
- /**
- * @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
- * @return {?function(!WebInspector.TimelineProfileTree.Node):!WebInspector.TimelineProfileTree.Node}
- */
- groupFunction(groupBy) {
- var idMapper = this._nodeToGroupIdFunction(groupBy);
- return idMapper && this._nodeToGroupNode.bind(this, idMapper);
- }
-
- /**
* @param {!WebInspector.TimelineProfileTree.Node} root
- * @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
* @return {!WebInspector.TimelineProfileTree.Node}
*/
- performGrouping(root, groupBy) {
- var nodeMapper = this.groupFunction(groupBy);
- if (!nodeMapper)
- return root;
+ performGrouping(root) {
for (var node of root.children.values()) {
- var groupNode = nodeMapper(node);
+ var groupNode = this.groupNodeForId(node._groupId, node.event);
groupNode.parent = root;
groupNode.selfTime += node.selfTime;
groupNode.totalTime += node.totalTime;
@@ -271,56 +256,13 @@ WebInspector.TimelineAggregator = class {
}
/**
- * @param {!WebInspector.TimelineAggregator.GroupBy} groupBy
- * @return {?function(!WebInspector.TimelineProfileTree.Node):string}
+ * @param {string} groupId
+ * @param {!WebInspector.TracingModel.Event} event
+ * @return {!WebInspector.TimelineProfileTree.Node}
*/
- _nodeToGroupIdFunction(groupBy) {
- /**
- * @param {!WebInspector.TimelineProfileTree.Node} node
- * @return {string}
- */
- function groupByURL(node) {
- return WebInspector.TimelineProfileTree.eventURL(node.event) || '';
- }
-
- /**
- * @param {boolean} groupSubdomains
- * @param {!WebInspector.TimelineProfileTree.Node} node
- * @return {string}
- */
- function groupByDomain(groupSubdomains, node) {
- var url = WebInspector.TimelineProfileTree.eventURL(node.event) || '';
- if (WebInspector.TimelineAggregator.isExtensionInternalURL(url))
- return WebInspector.TimelineAggregator._extensionInternalPrefix;
- var parsedURL = url.asParsedURL();
- if (!parsedURL)
- return '';
- if (parsedURL.scheme === 'chrome-extension')
- return parsedURL.scheme + '://' + parsedURL.host;
- if (!groupSubdomains)
- return parsedURL.host;
- if (/^[.0-9]+$/.test(parsedURL.host))
- return parsedURL.host;
- var domainMatch = /([^.]*\.)?[^.]*$/.exec(parsedURL.host);
- return domainMatch && domainMatch[0] || '';
- }
-
- switch (groupBy) {
- case WebInspector.TimelineAggregator.GroupBy.None:
- return null;
- case WebInspector.TimelineAggregator.GroupBy.EventName:
- return node => node.event ? this._titleMapper(node.event) : '';
- case WebInspector.TimelineAggregator.GroupBy.Category:
- return node => node.event ? this._categoryMapper(node.event) : '';
- case WebInspector.TimelineAggregator.GroupBy.Subdomain:
- return groupByDomain.bind(null, false);
- case WebInspector.TimelineAggregator.GroupBy.Domain:
- return groupByDomain.bind(null, true);
- case WebInspector.TimelineAggregator.GroupBy.URL:
- return groupByURL;
- default:
- return null;
- }
+ groupNodeForId(groupId, event) {
+ var node = this._groupNodes.get(groupId);
+ return node || this._buildGroupNode(groupId, event);
}
/**
@@ -339,30 +281,6 @@ WebInspector.TimelineAggregator = class {
this._groupNodes.set(id, groupNode);
return groupNode;
}
-
- /**
- * @param {function(!WebInspector.TimelineProfileTree.Node):string} nodeToGroupId
- * @param {!WebInspector.TimelineProfileTree.Node} node
- * @return {!WebInspector.TimelineProfileTree.Node}
- */
- _nodeToGroupNode(nodeToGroupId, node) {
- var id = nodeToGroupId(node);
- return this._groupNodes.get(id) || this._buildGroupNode(id, node.event);
- }
};
-/**
- * @enum {string}
- */
-WebInspector.TimelineAggregator.GroupBy = {
- None: 'None',
- EventName: 'EventName',
- Category: 'Category',
- Domain: 'Domain',
- Subdomain: 'Subdomain',
- URL: 'URL'
-};
-
-
-WebInspector.TimelineAggregator._extensionInternalPrefix = 'extensions::';
WebInspector.TimelineAggregator._groupNodeFlag = Symbol('groupNode');
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698