Web Inspector: Timelines: CPU/memory timeline bars sometimes don't draw correctly and jump around on scrolling
https://bugs.webkit.org/show_bug.cgi?id=197440
<rdar://problem/46886315>
Reviewed by Joseph Pecoraro.
When drawing the Memory/CPU graphs, we need to know about the record immediately before/after
what's overlapping the visible range so that the graph correctly slopes off the screen.
* UserInterface/Models/Timeline.js:
(WI.Timeline.prototype.recordsInTimeRange):
(WI.Timeline.prototype.recordsOverlappingTimeRange): Deleted.
Merge `recordsOverlappingTimeRange` into `recordsInTimeRange` by accepting an options object
that determines whether to include the record before/after the first/last record that are
at all overlapping the range.
* UserInterface/Models/CPUTimelineRecord.js:
(WI.CPUTimelineRecord):
(WI.CPUTimelineRecord.get samplingRatePerSecond): Added.
(WI.CPUTimelineRecord.prototype.adjustStartTimeToLastRecord): Added.
* UserInterface/Models/MemoryTimelineRecord.js:
(WI.MemoryTimelineRecord):
(WI.MemoryTimelineRecord.get samplingRatePerSecond): Added.
(WI.MemoryTimelineRecord.prototype.adjustStartTimeToLastRecord): Added.
Adjust the `startTime` of the record by the sampling rate (which is 500ms).
* UserInterface/Models/CPUTimeline.js: Added.
(WI.CPUTimeline.prototype.addRecord):
* UserInterface/Models/MemoryTimeline.js:
(WI.MemoryTimeline.prototype.addRecord): Added.
Adjust the `startTime` of the new record to be equal to the `endTime` of the last record.
* UserInterface/Views/TimelineOverview.js:
(WI.TimelineOverview.prototype._recordSelected):
* UserInterface/Views/CPUTimelineView.js:
(WI.CPUTimelineView.prototype.layout):
(WI.CPUTimelineView.prototype._computeStatisticsData):
(WI.CPUTimelineView.prototype._attemptSelectIndicatatorTimelineRecord):
* UserInterface/Views/CPUTimelineOverviewGraph.js:
(WI.CPUTimelineOverviewGraph.prototype.layout):
(WI.CPUTimelineOverviewGraph.prototype._handleChartClick):
(WI.CPUTimelineOverviewGraph.prototype.get samplingRatePerSecond): Deleted.
(WI.CPUTimelineOverviewGraph.prototype.layout.yScaleForRecord): Deleted.
* UserInterface/Views/MemoryTimelineView.js:
(WI.MemoryTimelineView.prototype.layout):
* UserInterface/Views/MemoryTimelineOverviewGraph.js:
(WI.MemoryTimelineOverviewGraph.prototype.layout):
* UserInterface/Main.html:
* UserInterface/Test.html:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245498 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog
index 26470e0..d76efb6 100644
--- a/Source/WebInspectorUI/ChangeLog
+++ b/Source/WebInspectorUI/ChangeLog
@@ -1,5 +1,59 @@
2019-05-17 Devin Rousso <drousso@apple.com>
+ Web Inspector: Timelines: CPU/memory timeline bars sometimes don't draw correctly and jump around on scrolling
+ https://bugs.webkit.org/show_bug.cgi?id=197440
+ <rdar://problem/46886315>
+
+ Reviewed by Joseph Pecoraro.
+
+ When drawing the Memory/CPU graphs, we need to know about the record immediately before/after
+ what's overlapping the visible range so that the graph correctly slopes off the screen.
+
+ * UserInterface/Models/Timeline.js:
+ (WI.Timeline.prototype.recordsInTimeRange):
+ (WI.Timeline.prototype.recordsOverlappingTimeRange): Deleted.
+ Merge `recordsOverlappingTimeRange` into `recordsInTimeRange` by accepting an options object
+ that determines whether to include the record before/after the first/last record that are
+ at all overlapping the range.
+
+ * UserInterface/Models/CPUTimelineRecord.js:
+ (WI.CPUTimelineRecord):
+ (WI.CPUTimelineRecord.get samplingRatePerSecond): Added.
+ (WI.CPUTimelineRecord.prototype.adjustStartTimeToLastRecord): Added.
+ * UserInterface/Models/MemoryTimelineRecord.js:
+ (WI.MemoryTimelineRecord):
+ (WI.MemoryTimelineRecord.get samplingRatePerSecond): Added.
+ (WI.MemoryTimelineRecord.prototype.adjustStartTimeToLastRecord): Added.
+ Adjust the `startTime` of the record by the sampling rate (which is 500ms).
+
+ * UserInterface/Models/CPUTimeline.js: Added.
+ (WI.CPUTimeline.prototype.addRecord):
+ * UserInterface/Models/MemoryTimeline.js:
+ (WI.MemoryTimeline.prototype.addRecord): Added.
+ Adjust the `startTime` of the new record to be equal to the `endTime` of the last record.
+
+ * UserInterface/Views/TimelineOverview.js:
+ (WI.TimelineOverview.prototype._recordSelected):
+ * UserInterface/Views/CPUTimelineView.js:
+ (WI.CPUTimelineView.prototype.layout):
+ (WI.CPUTimelineView.prototype._computeStatisticsData):
+ (WI.CPUTimelineView.prototype._attemptSelectIndicatatorTimelineRecord):
+ * UserInterface/Views/CPUTimelineOverviewGraph.js:
+ (WI.CPUTimelineOverviewGraph.prototype.layout):
+ (WI.CPUTimelineOverviewGraph.prototype._handleChartClick):
+ (WI.CPUTimelineOverviewGraph.prototype.get samplingRatePerSecond): Deleted.
+ (WI.CPUTimelineOverviewGraph.prototype.layout.yScaleForRecord): Deleted.
+
+ * UserInterface/Views/MemoryTimelineView.js:
+ (WI.MemoryTimelineView.prototype.layout):
+ * UserInterface/Views/MemoryTimelineOverviewGraph.js:
+ (WI.MemoryTimelineOverviewGraph.prototype.layout):
+
+ * UserInterface/Main.html:
+ * UserInterface/Test.html:
+
+2019-05-17 Devin Rousso <drousso@apple.com>
+
Web Inspector: Audit: make it easier to jump to any returned DOM node in the Elements tab
https://bugs.webkit.org/show_bug.cgi?id=197470
<rdar://problem/50466774>
diff --git a/Source/WebInspectorUI/UserInterface/Main.html b/Source/WebInspectorUI/UserInterface/Main.html
index 981655e..6b4d613 100644
--- a/Source/WebInspectorUI/UserInterface/Main.html
+++ b/Source/WebInspectorUI/UserInterface/Main.html
@@ -356,6 +356,7 @@
<script src="Models/Branch.js"></script>
<script src="Models/Breakpoint.js"></script>
<script src="Models/CPUInstrument.js"></script>
+ <script src="Models/CPUTimeline.js"></script>
<script src="Models/CPUTimelineRecord.js"></script>
<script src="Models/CSSCompletions.js"></script>
<script src="Models/CSSKeywordCompletions.js"></script>
diff --git a/Source/WebInspectorUI/UserInterface/Models/CPUTimeline.js b/Source/WebInspectorUI/UserInterface/Models/CPUTimeline.js
new file mode 100644
index 0000000..128022f
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Models/CPUTimeline.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.CPUTimeline = class CPUTimeline extends WI.Timeline
+{
+ // Public
+
+ addRecord(record)
+ {
+ let lastRecord = this.records.lastValue;
+ if (lastRecord)
+ record.adjustStartTimeToLastRecord(lastRecord);
+
+ super.addRecord(record);
+ }
+};
diff --git a/Source/WebInspectorUI/UserInterface/Models/CPUTimelineRecord.js b/Source/WebInspectorUI/UserInterface/Models/CPUTimelineRecord.js
index 2166891..112b713 100644
--- a/Source/WebInspectorUI/UserInterface/Models/CPUTimelineRecord.js
+++ b/Source/WebInspectorUI/UserInterface/Models/CPUTimelineRecord.js
@@ -27,7 +27,7 @@
{
constructor({timestamp, usage, threads})
{
- super(WI.TimelineRecord.Type.CPU, timestamp, timestamp);
+ super(WI.TimelineRecord.Type.CPU, timestamp - CPUTimelineRecord.samplingRatePerSecond, timestamp);
console.assert(typeof timestamp === "number");
console.assert(typeof usage === "number");
@@ -68,6 +68,14 @@
}
}
+ // Static
+
+ static get samplingRatePerSecond()
+ {
+ // 500ms. This matches the ResourceUsageThread sampling frequency in the backend.
+ return 0.5;
+ }
+
// Import / Export
static fromJSON(json)
@@ -95,4 +103,11 @@
get workerThreadUsage() { return this._workerThreadUsage; }
get unknownThreadUsage() { return this._unknownThreadUsage; }
get workersData() { return this._workersData; }
+
+ adjustStartTimeToLastRecord(lastRecord)
+ {
+ console.assert(lastRecord instanceof CPUTimelineRecord);
+ console.assert(this._startTime >= lastRecord.endTime);
+ this._startTime = lastRecord.endTime;
+ }
};
diff --git a/Source/WebInspectorUI/UserInterface/Models/MemoryTimeline.js b/Source/WebInspectorUI/UserInterface/Models/MemoryTimeline.js
index a2f109b..4b4f060 100644
--- a/Source/WebInspectorUI/UserInterface/Models/MemoryTimeline.js
+++ b/Source/WebInspectorUI/UserInterface/Models/MemoryTimeline.js
@@ -46,6 +46,15 @@
this._pressureEvents = [];
}
+
+ addRecord(record)
+ {
+ let lastRecord = this.records.lastValue;
+ if (lastRecord)
+ record.adjustStartTimeToLastRecord(lastRecord);
+
+ super.addRecord(record);
+ }
};
WI.MemoryTimeline.Event = {
diff --git a/Source/WebInspectorUI/UserInterface/Models/MemoryTimelineRecord.js b/Source/WebInspectorUI/UserInterface/Models/MemoryTimelineRecord.js
index 1e37b9a..787bedc 100644
--- a/Source/WebInspectorUI/UserInterface/Models/MemoryTimelineRecord.js
+++ b/Source/WebInspectorUI/UserInterface/Models/MemoryTimelineRecord.js
@@ -27,7 +27,7 @@
{
constructor(timestamp, categories)
{
- super(WI.TimelineRecord.Type.Memory, timestamp, timestamp);
+ super(WI.TimelineRecord.Type.Memory, timestamp - MemoryTimelineRecord.samplingRatePerSecond, timestamp);
console.assert(typeof timestamp === "number");
console.assert(categories instanceof Array);
@@ -43,6 +43,12 @@
// Static
+ static get samplingRatePerSecond()
+ {
+ // 500ms. This matches the ResourceUsageThread sampling frequency in the backend.
+ return 0.5;
+ }
+
static memoryCategoriesFromProtocol(categories)
{
let javascriptSize = 0;
@@ -102,4 +108,11 @@
get timestamp() { return this._timestamp; }
get categories() { return this._categories; }
get totalSize() { return this._totalSize; }
+
+ adjustStartTimeToLastRecord(lastRecord)
+ {
+ console.assert(lastRecord instanceof MemoryTimelineRecord);
+ console.assert(this._startTime >= lastRecord.endTime);
+ this._startTime = lastRecord.endTime;
+ }
};
diff --git a/Source/WebInspectorUI/UserInterface/Models/Timeline.js b/Source/WebInspectorUI/UserInterface/Models/Timeline.js
index 0be7ec5..28f4252 100644
--- a/Source/WebInspectorUI/UserInterface/Models/Timeline.js
+++ b/Source/WebInspectorUI/UserInterface/Models/Timeline.js
@@ -41,6 +41,9 @@
if (type === WI.TimelineRecord.Type.Network)
return new WI.NetworkTimeline(type);
+ if (type === WI.TimelineRecord.Type.CPU)
+ return new WI.CPUTimeline(type);
+
if (type === WI.TimelineRecord.Type.Memory)
return new WI.MemoryTimeline(type);
@@ -111,20 +114,9 @@
return (before < after) ? recordBefore : recordAfter;
}
- recordsOverlappingTimeRange(startTime, endTime)
+ recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart, includeRecordAfterEnd} = {})
{
let lowerIndex = this._records.lowerBound(startTime, (time, record) => time - record.endTime);
- let upperIndex = this._records.upperBound(endTime, (time, record) => time - record.startTime);
-
- return this._records.slice(lowerIndex, upperIndex);
- }
-
- recordsInTimeRange(startTime, endTime, includeRecordBeforeStart)
- {
- let lowerIndex = this._records.lowerBound(startTime, (time, record) => time - record.startTime);
- let upperIndex = this._records.upperBound(endTime, (time, record) => time - record.startTime);
-
- // Include the record right before the start time.
if (includeRecordBeforeStart && lowerIndex > 0) {
lowerIndex--;
@@ -137,6 +129,10 @@
}
}
+ let upperIndex = this._records.upperBound(endTime, (time, record) => time - record.startTime);
+ if (includeRecordAfterEnd && upperIndex < this._records.length)
+ ++upperIndex;
+
return this._records.slice(lowerIndex, upperIndex);
}
diff --git a/Source/WebInspectorUI/UserInterface/Test.html b/Source/WebInspectorUI/UserInterface/Test.html
index 06f0be2..e710ec6 100644
--- a/Source/WebInspectorUI/UserInterface/Test.html
+++ b/Source/WebInspectorUI/UserInterface/Test.html
@@ -118,6 +118,7 @@
<script src="Models/Breakpoint.js"></script>
<script src="Models/CPUInstrument.js"></script>
+ <script src="Models/CPUTimeline.js"></script>
<script src="Models/CPUTimelineRecord.js"></script>
<script src="Models/CSSCompletions.js"></script>
<script src="Models/CSSKeywordCompletions.js"></script>
diff --git a/Source/WebInspectorUI/UserInterface/Views/CPUTimelineOverviewGraph.js b/Source/WebInspectorUI/UserInterface/Views/CPUTimelineOverviewGraph.js
index 087a4a6..024314c 100644
--- a/Source/WebInspectorUI/UserInterface/Views/CPUTimelineOverviewGraph.js
+++ b/Source/WebInspectorUI/UserInterface/Views/CPUTimelineOverviewGraph.js
@@ -56,14 +56,6 @@
this._processRecord(record);
}
- // Static
-
- static get samplingRatePerSecond()
- {
- // 500ms. This matches the ResourceUsageThread sampling frequency in the backend.
- return 0.5;
- }
-
// Protected
get height()
@@ -115,22 +107,18 @@
return (size / maxCapacity) * height;
}
- const includeRecordBeforeStart = true;
- let visibleRecords = this._cpuTimeline.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
+ let visibleRecords = this._cpuTimeline.recordsInTimeRange(graphStartTime, visibleEndTime, {
+ includeRecordBeforeStart: true,
+ });
if (!visibleRecords.length)
return;
- function yScaleForRecord(record) {
- return yScale(record.usage);
- }
-
- let intervalWidth = CPUTimelineOverviewGraph.samplingRatePerSecond / secondsPerPixel;
const minimumDisplayHeight = 4;
for (let record of visibleRecords) {
let additionalClass = record === this.selectedRecord ? "selected" : undefined;
- let w = intervalWidth;
- let x = xScale(record.startTime - CPUTimelineOverviewGraph.samplingRatePerSecond);
+ let w = (record.endTime - record.startTime) / secondsPerPixel;
+ let x = xScale(record.startTime);
let h1 = Math.max(minimumDisplayHeight, yScale(record.mainThreadUsage));
let h2 = Math.max(minimumDisplayHeight, yScale(record.mainThreadUsage + record.workerThreadUsage));
let h3 = Math.max(minimumDisplayHeight, yScale(record.usage));
@@ -199,7 +187,7 @@
let graphStartTime = this.startTime;
let clickTime = graphStartTime + graphClickTime;
- let record = this._cpuTimeline.closestRecordTo(clickTime + (CPUTimelineOverviewGraph.samplingRatePerSecond / 2));
+ let record = this._cpuTimeline.closestRecordTo(clickTime);
if (!record)
return;
diff --git a/Source/WebInspectorUI/UserInterface/Views/CPUTimelineView.js b/Source/WebInspectorUI/UserInterface/Views/CPUTimelineView.js
index 1513d4e..365421d 100644
--- a/Source/WebInspectorUI/UserInterface/Views/CPUTimelineView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/CPUTimelineView.js
@@ -445,9 +445,10 @@
let discontinuities = this._recording.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
let originalDiscontinuities = discontinuities.slice();
- // Don't include the record before the graph start if the graph start is within a gap.
- let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;
- let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
+ let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, {
+ includeRecordBeforeStart: !discontinuities.length || discontinuities[0].startTime > graphStartTime,
+ includeRecordAfterEnd: true,
+ });
if (!visibleRecords.length || (visibleRecords.length === 1 && visibleRecords[0].endTime < graphStartTime)) {
this.clear();
return;
@@ -1161,8 +1162,6 @@
// with the data available to the frontend and is quite accurate for most
// Main Thread activity.
- const includeRecordBeforeStart = true;
-
function incrementTypeCount(map, key) {
let entry = map.get(key);
if (entry)
@@ -1183,7 +1182,7 @@
let possibleRepeatingTimers = new Set;
let scriptTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Script);
- let scriptRecords = scriptTimeline ? scriptTimeline.recordsInTimeRange(startTime, endTime, includeRecordBeforeStart) : [];
+ let scriptRecords = scriptTimeline ? scriptTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
scriptRecords = scriptRecords.filter((record) => {
// Return true for event types that define script entries/exits.
// Return false for events with no time ranges or if they are contained in other events.
@@ -1249,7 +1248,7 @@
});
let layoutTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Layout);
- let layoutRecords = layoutTimeline ? layoutTimeline.recordsInTimeRange(startTime, endTime, includeRecordBeforeStart) : [];
+ let layoutRecords = layoutTimeline ? layoutTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
layoutRecords = layoutRecords.filter((record) => {
switch (record.eventType) {
case WI.LayoutTimelineRecord.EventType.RecalculateStyles:
@@ -1573,7 +1572,7 @@
_attemptSelectIndicatatorTimelineRecord(startTime, endTime)
{
let layoutTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Layout);
- let layoutRecords = layoutTimeline ? layoutTimeline.recordsOverlappingTimeRange(startTime, endTime) : [];
+ let layoutRecords = layoutTimeline ? layoutTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
layoutRecords = layoutRecords.filter((record) => {
switch (record.eventType) {
case WI.LayoutTimelineRecord.EventType.RecalculateStyles:
@@ -1597,7 +1596,7 @@
}
let scriptTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Script);
- let scriptRecords = scriptTimeline ? scriptTimeline.recordsOverlappingTimeRange(startTime, endTime) : [];
+ let scriptRecords = scriptTimeline ? scriptTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
scriptRecords = scriptRecords.filter((record) => {
switch (record.eventType) {
case WI.ScriptTimelineRecord.EventType.ScriptEvaluated:
diff --git a/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js b/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js
index 496092f..f272287 100644
--- a/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js
+++ b/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js
@@ -138,11 +138,10 @@
let discontinuities = this.timelineOverview.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
- // Don't include the record before the graph start if the graph start is within a gap.
- let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;
-
- // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
- let visibleRecords = this._memoryTimeline.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
+ let visibleRecords = this._memoryTimeline.recordsInTimeRange(graphStartTime, visibleEndTime, {
+ includeRecordBeforeStart: !discontinuities.length || discontinuities[0].startTime > graphStartTime,
+ includeRecordAfterEnd: true,
+ });
if (!visibleRecords.length)
return;
diff --git a/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js b/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js
index 5172770..31e3dbb 100644
--- a/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js
@@ -197,11 +197,10 @@
let discontinuities = this._recording.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
- // Don't include the record before the graph start if the graph start is within a gap.
- let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;
-
- // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
- let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
+ let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, {
+ includeRecordBeforeStart: !discontinuities.length || discontinuities[0].startTime > graphStartTime,
+ includeRecordAfterEnd: true,
+ });
if (!visibleRecords.length || (visibleRecords.length === 1 && visibleRecords[0].endTime < graphStartTime)) {
this.clear();
return;
diff --git a/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js b/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js
index 3cec4fb..f11cff7 100644
--- a/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js
+++ b/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js
@@ -784,12 +784,7 @@
let startTime = firstRecord instanceof WI.RenderingFrameTimelineRecord ? firstRecord.frameIndex : firstRecord.startTime;
let endTime = lastRecord instanceof WI.RenderingFrameTimelineRecord ? lastRecord.frameIndex : lastRecord.endTime;
-
- if (firstRecord instanceof WI.CPUTimelineRecord) {
- let selectionPadding = WI.CPUTimelineOverviewGraph.samplingRatePerSecond * 2.25;
- this.selectionStartTime = startTime - selectionPadding - (WI.CPUTimelineOverviewGraph.samplingRatePerSecond / 2);
- this.selectionDuration = endTime - startTime + (selectionPadding * 2);
- } else if (startTime < this.selectionStartTime || endTime > this.selectionStartTime + this.selectionDuration) {
+ if (startTime < this.selectionStartTime || (endTime > this.selectionStartTime + this.selectionDuration) || firstRecord instanceof WI.CPUTimelineRecord) {
let selectionPadding = this.secondsPerPixel * 10;
this.selectionStartTime = startTime - selectionPadding;
this.selectionDuration = endTime - startTime + (selectionPadding * 2);