Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js |
| index bbde72162b802b689c97856758d626c5c3f7d5bf..ca95548d0a05534338375edd8ec307e5758b05cf 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js |
| @@ -204,6 +204,7 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar { |
| */ |
| _stop() { |
| return this._protocolService.detach().then(_ => { |
| + Emulation.InspectedPagePlaceholder.instance().update(); |
| this._auditRunning = false; |
| this._updateButton(); |
| var resourceTreeModel = SDK.targetManager.mainTarget().model(SDK.ResourceTreeModel); |
| @@ -514,6 +515,76 @@ Audits2.Audits2Panel.TreeElement = class extends UI.TreeElement { |
| renderer.setTemplateContext(templatesDOM); |
| renderer.renderReport(this._lighthouseResult, this._reportContainer); |
| + |
| + var performanceScoreElement = this._reportContainer.querySelector('.lh-category[id=performance] .lh-score'); |
| + var artifacts = this._lighthouseResult['artifacts']; |
| + if (!performanceScoreElement || !artifacts) |
| + return; |
| + var tracePass = artifacts['traces'] ? artifacts['traces']['defaultPass'] : null; |
| + if (!tracePass) |
| + return; |
| + |
| + var fmp = this._lighthouseResult['audits']['first-meaningful-paint']; |
| + if (!fmp || !fmp['extendedInfo']) |
| + return; |
| + |
| + var tti = this._lighthouseResult['audits']['time-to-interactive']; |
| + if (!tti || !tti['extendedInfo']) |
| + return; |
| + |
| + var navStart = fmp['extendedInfo']['value']['timestamps']['navStart']; |
| + var markers = [ |
| + { |
| + title: Common.UIString('First contentful paint'), |
| + value: (fmp['extendedInfo']['value']['timestamps']['fCP'] - navStart) / 1000 |
| + }, |
| + { |
| + title: Common.UIString('First meaningful paint'), |
| + value: (fmp['extendedInfo']['value']['timestamps']['fMP'] - navStart) / 1000 |
| + }, |
| + { |
| + title: Common.UIString('Time to interactive'), |
| + value: (tti['extendedInfo']['value']['timestamps']['timeToInteractive'] - navStart) / 1000 |
| + }, |
| + { |
| + title: Common.UIString('Visually ready'), |
| + value: (tti['extendedInfo']['value']['timestamps']['visuallyReady'] - navStart) / 1000 |
| + } |
| + ]; |
| + |
| + var screenshots = tracePass.traceEvents.filter(e => e.cat === 'disabled-by-default-devtools.screenshot'); |
| + var timelineElement = createElementWithClass('div', 'audits2-timeline'); |
| + var filmStripElement = timelineElement.createChild('div', 'audits2-filmstrip'); |
| + var lastEvent = screenshots.peekLast(); |
| + |
| + var numberOfFrames = 8 + 1; |
| + var roundToFraction = 4; |
| + var timeSpan = (lastEvent.ts - navStart) / 1000; |
| + var timeStep = (Math.ceil(timeSpan / numberOfFrames * roundToFraction / 1000)) / roundToFraction * 1000; |
| + |
| + for (var time = timeStep; time <= timeSpan; time += timeStep) { |
|
paulirish
2017/05/04 23:06:31
a single screenshot trace will be a problem here.
|
| + var frameForTime = null; |
| + for (var e of screenshots) { |
| + if ((e.ts - navStart) / 1000 < time) |
| + frameForTime = e.args.snapshot; |
| + } |
| + if (!frameForTime) |
|
paulirish
2017/05/04 23:06:31
we'll want empty frames at the start if the first
|
| + continue; |
| + var frame = filmStripElement.createChild('div', 'frame'); |
| + frame.createChild('div', 'time').textContent = Number.millisToString(time); |
| + var img = frame.createChild('div', 'thumbnail').createChild('img'); |
| + img.src = 'data:image/jpg;base64,' + frameForTime; |
| + } |
| + |
| + for (var marker of markers) { |
| + var markerElement = timelineElement.createChild('div', 'audits2-timeline-marker'); |
| + markerElement.createChild('div', 'audits2-timeline-bar').style.width = |
| + (100 * (marker.value / timeSpan) | 0) + '%'; |
| + markerElement.createChild('span').textContent = Common.UIString('%s: ', marker.title); |
| + markerElement.createChild('span', 'audits2-timeline-subtitle').textContent = Number.millisToString(marker.value); |
| + } |
| + |
| + performanceScoreElement.parentElement.insertBefore(timelineElement, performanceScoreElement.nextSibling); |
| } |
| }; |