Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js |
| index c193346d8562b595e766cb362e6d9e64dbb9488e..cdc6a36ec6f1f7c1a7e80635dbc6a4abb464f543 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js |
| @@ -644,6 +644,21 @@ TimelineModel.TimelineModel = class { |
| var recordTypes = TimelineModel.TimelineModel.RecordType; |
| + if (!eventStack.length) { |
| + if (this._currentTaskLayoutAndRecalcEvents && this._currentTaskLayoutAndRecalcEvents.length) { |
|
alph
2016/11/19 05:36:27
It won't work for the very last top level event.
|
| + var totalTime = this._currentTaskLayoutAndRecalcEvents.reduce((time, event) => time + event.duration, 0); |
|
alph
2016/11/19 05:36:27
We use const if the value is never changed.
|
| + if (totalTime > TimelineModel.TimelineModel.Thresholds.ForcedLayout) { |
| + for (var e of this._currentTaskLayoutAndRecalcEvents) { |
| + var timelineData = TimelineModel.TimelineData.forEvent(e); |
|
caseq
2016/11/19 05:51:08
This has the same name as a different variable bel
|
| + timelineData.warning = e.name === recordTypes.Layout ? |
| + TimelineModel.TimelineModel.WarningType.ForcedLayout : |
| + TimelineModel.TimelineModel.WarningType.ForcedStyle; |
| + } |
| + } |
| + } |
| + this._currentTaskLayoutAndRecalcEvents = []; |
| + } |
| + |
| if (this._currentScriptEvent && event.startTime > this._currentScriptEvent.endTime) |
| this._currentScriptEvent = null; |
| @@ -682,7 +697,7 @@ TimelineModel.TimelineModel = class { |
| timelineData.setInitiator(this._lastScheduleStyleRecalculation[event.args['beginData']['frame']]); |
| this._lastRecalculateStylesEvent = event; |
| if (this._currentScriptEvent) |
| - timelineData.warning = TimelineModel.TimelineModel.WarningType.ForcedStyle; |
| + this._currentTaskLayoutAndRecalcEvents.push(event); |
| break; |
| case recordTypes.ScheduleStyleInvalidationTracking: |
| @@ -715,7 +730,7 @@ TimelineModel.TimelineModel = class { |
| timelineData.backendNodeId = event.args['endData']['rootNode']; |
| this._layoutInvalidate[frameId] = null; |
| if (this._currentScriptEvent) |
| - timelineData.warning = TimelineModel.TimelineModel.WarningType.ForcedLayout; |
| + this._currentTaskLayoutAndRecalcEvents.push(event); |
| break; |
| case recordTypes.FunctionCall: |
| @@ -724,14 +739,35 @@ TimelineModel.TimelineModel = class { |
| eventData['url'] = eventData['scriptName']; |
| if (typeof eventData['scriptLine'] === 'number') |
| eventData['lineNumber'] = eventData['scriptLine']; |
| + |
| + if (event.duration > TimelineModel.TimelineModel.Thresholds.Handler) { |
| + var parentEvent = eventStack.peekLast(); |
| + if (parentEvent && parentEvent.name === recordTypes.EventDispatch) { |
|
caseq
2016/11/19 05:51:08
Why do it here? Let's do it when handling correspo
|
| + TimelineModel.TimelineData.forEvent(parentEvent).warning = |
| + TimelineModel.TimelineModel.WarningType.LongHandler; |
| + } |
| + } |
| + |
| + if (event.duration > TimelineModel.TimelineModel.Thresholds.RecurringHandler) { |
| + var parentEvent = eventStack.peekLast(); |
| + if (parentEvent && |
| + (parentEvent.name === recordTypes.TimerFire || parentEvent.name === recordTypes.FireAnimationFrame)) { |
|
caseq
2016/11/19 05:51:08
ditto.
|
| + TimelineModel.TimelineData.forEvent(parentEvent).warning = |
| + TimelineModel.TimelineModel.WarningType.LongRecurringHandler; |
| + } |
| + } |
| + |
| // Fallthrough. |
| + |
| case recordTypes.EvaluateScript: |
| case recordTypes.CompileScript: |
| if (typeof eventData['lineNumber'] === 'number') |
| --eventData['lineNumber']; |
| if (typeof eventData['columnNumber'] === 'number') |
| --eventData['columnNumber']; |
| + |
| // Fallthrough intended. |
| + |
| case recordTypes.RunMicrotasks: |
| // Microtasks technically are not necessarily scripts, but for purpose of |
| // forced sync style recalc or layout detection they are. |
| @@ -828,9 +864,9 @@ TimelineModel.TimelineModel = class { |
| break; |
| case recordTypes.FireIdleCallback: |
| - if (event.duration > eventData['allottedMilliseconds']) |
| + if (event.duration > |
| + eventData['allottedMilliseconds'] + TimelineModel.TimelineModel.Thresholds.IdleCallbackAddon) |
| timelineData.warning = TimelineModel.TimelineModel.WarningType.IdleDeadlineExceeded; |
| - |
| break; |
| } |
| if (SDK.TracingModel.isAsyncPhase(event.phase)) |
| @@ -1250,6 +1286,8 @@ TimelineModel.TimelineModel.WarningType = { |
| ForcedStyle: 'ForcedStyle', |
| ForcedLayout: 'ForcedLayout', |
| IdleDeadlineExceeded: 'IdleDeadlineExceeded', |
| + LongHandler: 'LongHandler', |
| + LongRecurringHandler: 'LongRecurringHandler', |
| V8Deopt: 'V8Deopt' |
| }; |
| @@ -1274,6 +1312,13 @@ TimelineModel.TimelineModel.DevToolsMetadataEvent = { |
| TracingSessionIdForWorker: 'TracingSessionIdForWorker', |
| }; |
| +TimelineModel.TimelineModel.Thresholds = { |
| + Handler: 150, |
|
alph
2016/11/19 05:36:27
Perhaps, there should be different types of handle
|
| + RecurringHandler: 50, |
| + ForcedLayout: 30, |
| + IdleCallbackAddon: 5 |
| +}; |
| + |
| /** |
| * @unrestricted |
| */ |