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

Unified Diff: Source/devtools/front_end/timeline/TimelineModel.js

Issue 731293006: Implement style invalidation tracking (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address reviewer comments, cleanup Created 6 years 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
Index: Source/devtools/front_end/timeline/TimelineModel.js
diff --git a/Source/devtools/front_end/timeline/TimelineModel.js b/Source/devtools/front_end/timeline/TimelineModel.js
index 186fede5f58e963dea110338aef98dd913c6ec57..cc81884ac5b3fafbf5199de78ae4267ea11046a3 100644
--- a/Source/devtools/front_end/timeline/TimelineModel.js
+++ b/Source/devtools/front_end/timeline/TimelineModel.js
@@ -74,7 +74,9 @@ WebInspector.TimelineModel.RecordType = {
ScrollLayer: "ScrollLayer",
CompositeLayers: "CompositeLayers",
+ ScheduleStyleInvalidationTracking: "ScheduleStyleInvalidationTracking",
StyleRecalcInvalidationTracking: "StyleRecalcInvalidationTracking",
+ StyleInvalidatorInvalidationTracking: "StyleInvalidatorInvalidationTracking",
LayoutInvalidationTracking: "LayoutInvalidationTracking",
LayerInvalidationTracking: "LayerInvalidationTracking",
PaintInvalidationTracking: "PaintInvalidationTracking",
@@ -951,11 +953,13 @@ WebInspector.TimelineModel.prototype = {
this._lastRecalculateStylesEvent = event;
break;
+ case recordTypes.ScheduleStyleInvalidationTracking:
case recordTypes.StyleRecalcInvalidationTracking:
+ case recordTypes.StyleInvalidatorInvalidationTracking:
case recordTypes.LayoutInvalidationTracking:
case recordTypes.LayerInvalidationTracking:
case recordTypes.PaintInvalidationTracking:
- this._invalidationTracker.addInvalidation(event);
+ this._invalidationTracker.addInvalidation(new WebInspector.InvalidationTrackingEvent(event));
break;
case recordTypes.InvalidateLayout:
@@ -1664,20 +1668,47 @@ WebInspector.TracingTimelineSaver.prototype = {
*/
WebInspector.InvalidationTrackingEvent = function(event)
{
+ /** @type {string} */
this.type = event.name;
- this.frameId = event.args["data"]["frame"];
- this.nodeId = event.args["data"]["nodeId"];
- this.nodeName = event.args["data"]["nodeName"];
- this.paintId = event.args["data"]["paintId"];
-
- var reason = event.args["data"]["reason"];
- var stackTrace = event.args["data"]["stackTrace"];
-
- if (!reason && stackTrace && this.type === WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking)
- reason = "Layout forced";
-
- if (reason || stackTrace)
- this.cause = {reason: reason, stackTrace: stackTrace};
+ /** @type {number} */
+ this.startTime = event.startTime;
+ /** @type {!WebInspector.TracingModel.Event} */
+ this._tracingEvent = event;
+
+ var eventData = event.args["data"];
+
+ /** @type {number} */
+ this.frame = eventData["frame"];
+ /** @type {?number} */
+ this.nodeId = eventData["nodeId"];
+ /** @type {?string} */
+ this.nodeName = eventData["nodeName"];
+ /** @type {?number} */
+ this.paintId = eventData["paintId"];
+ /** @type {?number} */
+ this.invalidationSet = eventData["invalidationSet"];
+ /** @type {?string} */
+ this.invalidatedSelectorId = eventData["invalidatedSelectorId"];
+ /** @type {?string} */
+ this.changedId = eventData["changedId"];
+ /** @type {?string} */
+ this.changedClass = eventData["changedClass"];
+ /** @type {?string} */
+ this.changedAttribute = eventData["changedAttribute"];
+ /** @type {?string} */
+ this.changedPseudo = eventData["changedPseudo"];
+ /** @type {?string} */
+ this.selectorPart = eventData["selectorPart"];
+ /** @type {?string} */
+ this.extraData = eventData["extraData"];
+ /** @type {?Array.<!Object.<string, number>>} */
+ this.invalidationList = eventData["invalidationList"];
+ /** @type {!WebInspector.InvalidationCause} */
+ this.cause = {reason: eventData["reason"], stackTrace: eventData["stackTrace"]};
+
+ // FIXME: Move this to TimelineUIUtils.js.
+ if (!this.cause.reason && this.cause.stackTrace && this.type === WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking)
+ this.cause.reason = "Layout forced";
}
/** @typedef {{reason: string, stackTrace: ?Array.<!ConsoleAgent.CallFrame>}} */
@@ -1693,11 +1724,10 @@ WebInspector.InvalidationTracker = function()
WebInspector.InvalidationTracker.prototype = {
/**
- * @param {!WebInspector.TracingModel.Event} event
+ * @param {!WebInspector.InvalidationTrackingEvent} invalidation
*/
- addInvalidation: function(event)
+ addInvalidation: function(invalidation)
{
- var invalidation = new WebInspector.InvalidationTrackingEvent(event);
this._startNewFrameIfNeeded();
if (!invalidation.nodeId && !invalidation.paintId) {
@@ -1717,14 +1747,22 @@ WebInspector.InvalidationTracker.prototype = {
return;
}
- // StyleRecalcInvalidationTracking events can occur before and during
- // recalc style. didRecalcStyle handles StyleRecalcInvalidationTracking
- // events that occur before the recalc style event but we need to handle
- // StyleRecalcInvalidationTracking events during recalc style here.
- if (invalidation.type === recordTypes.StyleRecalcInvalidationTracking) {
- var duringRecalcStyle = event.startTime && this._lastRecalcStyle
- && event.startTime >= this._lastRecalcStyle.startTime
- && event.startTime <= this._lastRecalcStyle.endTime;
+ // Suppress StyleInvalidator StyleRecalcInvalidationTracking invalidations because they
+ // will be handled by StyleInvalidatorInvalidationTracking.
+ // FIXME: Investigate if we can remove StyleInvalidator invalidations entirely.
+ if (invalidation.type === recordTypes.StyleRecalcInvalidationTracking && invalidation.cause.reason === "StyleInvalidator")
+ return;
+
+ // Style invalidation events can occur before and during recalc style. didRecalcStyle
+ // handles style invalidations that occur before the recalc style event but we need to
+ // handle style recalc invalidations during recalc style here.
+ var styleRecalcInvalidation = (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking
+ || invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking
+ || invalidation.type === recordTypes.StyleRecalcInvalidationTracking);
+ if (styleRecalcInvalidation) {
+ var duringRecalcStyle = invalidation.startTime && this._lastRecalcStyle
+ && invalidation.startTime >= this._lastRecalcStyle.startTime
+ && invalidation.startTime <= this._lastRecalcStyle.endTime;
if (duringRecalcStyle)
this._associateWithLastRecalcStyleEvent(invalidation);
}
@@ -1752,8 +1790,10 @@ WebInspector.InvalidationTracker.prototype = {
didRecalcStyle: function(recalcStyleEvent)
{
this._lastRecalcStyle = recalcStyleEvent;
- this._forAllInvalidations(this._associateWithLastRecalcStyleEvent,
- [WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking]);
+ var types = [WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking,
+ WebInspector.TimelineModel.RecordType.StyleInvalidatorInvalidationTracking,
+ WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking];
+ this._forAllInvalidations(this._associateWithLastRecalcStyleEvent, types);
},
/**
@@ -1763,12 +1803,77 @@ WebInspector.InvalidationTracker.prototype = {
{
if (invalidation.linkedRecalcStyleEvent)
return;
+
+ var recordTypes = WebInspector.TimelineModel.RecordType;
var recalcStyleFrameId = this._lastRecalcStyle.args["beginData"]["frame"];
- this._addInvalidationToEvent(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
+ if (invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking) {
+ // Instead of calling _addInvalidationToEvent directly, we create synthetic
+ // StyleRecalcInvalidationTracking events which will be added in _addInvalidationToEvent.
+ this._addSyntheticStyleRecalcInvalidations(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
+ } else if (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking) {
+ // ScheduleStyleInvalidationTracking events are only used for adding information to
+ // StyleInvalidatorInvalidationTracking events. See: _addSyntheticStyleRecalcInvalidations.
+ } else {
+ this._addInvalidationToEvent(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
+ }
+
invalidation.linkedRecalcStyleEvent = true;
},
/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @param {number} frameId
+ * @param {!WebInspector.InvalidationTrackingEvent} styleInvalidatorInvalidation
+ */
+ _addSyntheticStyleRecalcInvalidations: function(event, frameId, styleInvalidatorInvalidation)
+ {
+ if (!styleInvalidatorInvalidation.invalidationList) {
+ this._addSyntheticStyleRecalcInvalidation(styleInvalidatorInvalidation._tracingEvent, styleInvalidatorInvalidation);
+ return;
+ }
+
+ for (var i = 0; i < styleInvalidatorInvalidation.invalidationList.length; i++) {
+ var setId = styleInvalidatorInvalidation.invalidationList[i]["id"];
+ var lastScheduleStyleRecalculation;
+
+ function findMatchingInvalidation(invalidation)
+ {
+ if (invalidation.frame !== frameId)
+ return;
+ if (invalidation.nodeId === styleInvalidatorInvalidation.nodeId && invalidation.invalidationSet === setId)
+ lastScheduleStyleRecalculation = invalidation;
+ }
+
+ this._forAllInvalidations(findMatchingInvalidation, [WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking]);
+
+ if (!lastScheduleStyleRecalculation) {
+ console.error("Failed to lookup the event that scheduled a style invalidator invalidation.");
+ continue;
+ }
+ this._addSyntheticStyleRecalcInvalidation(lastScheduleStyleRecalculation._tracingEvent, styleInvalidatorInvalidation);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} baseEvent
+ * @param {!WebInspector.InvalidationTrackingEvent} styleInvalidatorInvalidation
+ */
+ _addSyntheticStyleRecalcInvalidation: function(baseEvent, styleInvalidatorInvalidation)
+ {
+ var invalidation = new WebInspector.InvalidationTrackingEvent(baseEvent);
+ invalidation.type = WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking;
+ invalidation.synthetic = true;
+ if (styleInvalidatorInvalidation.cause.reason)
+ invalidation.cause.reason = styleInvalidatorInvalidation.cause.reason;
+ if (styleInvalidatorInvalidation.selectorPart)
+ invalidation.selectorPart = styleInvalidatorInvalidation.selectorPart;
+
+ this.addInvalidation(invalidation);
+ if (!invalidation.linkedRecalcStyleEvent)
+ this._associateWithLastRecalcStyleEvent(invalidation);
+ },
+
+ /**
* @param {!WebInspector.TracingModel.Event} layoutEvent
*/
didLayout: function(layoutEvent)
@@ -1810,7 +1915,10 @@ WebInspector.InvalidationTracker.prototype = {
var effectivePaintId = this._lastPaintWithLayer.args["data"]["nodeId"];
var paintFrameId = paintEvent.args["data"]["frame"];
- this._forAllInvalidations(associateWithPaintEvent);
+ var types = [WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking,
+ WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking,
+ WebInspector.TimelineModel.RecordType.PaintInvalidationTracking];
+ this._forAllInvalidations(associateWithPaintEvent, types);
/**
* @param {!WebInspector.InvalidationTrackingEvent} invalidation
@@ -1831,7 +1939,7 @@ WebInspector.InvalidationTracker.prototype = {
*/
_addInvalidationToEvent: function(event, eventFrameId, invalidation)
{
- if (eventFrameId !== invalidation.frameId)
+ if (eventFrameId !== invalidation.frame)
return;
if (!event.invalidationTrackingEvents)
event.invalidationTrackingEvents = [ invalidation ];

Powered by Google App Engine
This is Rietveld 408576698