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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js

Issue 2861053003: DevTools: [lighthouse] Implement performance metrics filmstrip (Closed)
Patch Set: Created 3 years, 7 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @unrestricted 6 * @unrestricted
7 */ 7 */
8 Audits2.Audits2Panel = class extends UI.PanelWithSidebar { 8 Audits2.Audits2Panel = class extends UI.PanelWithSidebar {
9 constructor() { 9 constructor() {
10 super('audits2'); 10 super('audits2');
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 if (!this._dialog) 197 if (!this._dialog)
198 return; 198 return;
199 this._statusElement.textContent = statusMessage; 199 this._statusElement.textContent = statusMessage;
200 } 200 }
201 201
202 /** 202 /**
203 * @return {!Promise<undefined>} 203 * @return {!Promise<undefined>}
204 */ 204 */
205 _stop() { 205 _stop() {
206 return this._protocolService.detach().then(_ => { 206 return this._protocolService.detach().then(_ => {
207 Emulation.InspectedPagePlaceholder.instance().update();
207 this._auditRunning = false; 208 this._auditRunning = false;
208 this._updateButton(); 209 this._updateButton();
209 var resourceTreeModel = SDK.targetManager.mainTarget().model(SDK.ResourceT reeModel); 210 var resourceTreeModel = SDK.targetManager.mainTarget().model(SDK.ResourceT reeModel);
210 if (resourceTreeModel && this._inspectedURL !== SDK.targetManager.mainTarg et().inspectedURL()) 211 if (resourceTreeModel && this._inspectedURL !== SDK.targetManager.mainTarg et().inspectedURL())
211 resourceTreeModel.navigate(this._inspectedURL).then(() => this._hideDial og()); 212 resourceTreeModel.navigate(this._inspectedURL).then(() => this._hideDial og());
212 else 213 else
213 this._hideDialog(); 214 this._hideDialog();
214 }); 215 });
215 } 216 }
216 217
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 var categoryRenderer = new CategoryRenderer(dom, detailsRenderer); 508 var categoryRenderer = new CategoryRenderer(dom, detailsRenderer);
508 var renderer = new Audits2.Audits2Panel.ReportRenderer(dom, categoryRenderer ); 509 var renderer = new Audits2.Audits2Panel.ReportRenderer(dom, categoryRenderer );
509 510
510 var templatesHTML = Runtime.cachedResources['audits2/lighthouse/templates.ht ml']; 511 var templatesHTML = Runtime.cachedResources['audits2/lighthouse/templates.ht ml'];
511 var templatesDOM = new DOMParser().parseFromString(templatesHTML, 'text/html '); 512 var templatesDOM = new DOMParser().parseFromString(templatesHTML, 'text/html ');
512 if (!templatesDOM) 513 if (!templatesDOM)
513 return; 514 return;
514 515
515 renderer.setTemplateContext(templatesDOM); 516 renderer.setTemplateContext(templatesDOM);
516 renderer.renderReport(this._lighthouseResult, this._reportContainer); 517 renderer.renderReport(this._lighthouseResult, this._reportContainer);
518
519 var performanceScoreElement = this._reportContainer.querySelector('.lh-categ ory[id=performance] .lh-score');
520 var artifacts = this._lighthouseResult['artifacts'];
521 if (!performanceScoreElement || !artifacts)
522 return;
523 var tracePass = artifacts['traces'] ? artifacts['traces']['defaultPass'] : n ull;
524 if (!tracePass)
525 return;
526
527 var fmp = this._lighthouseResult['audits']['first-meaningful-paint'];
528 if (!fmp || !fmp['extendedInfo'])
529 return;
530
531 var tti = this._lighthouseResult['audits']['time-to-interactive'];
532 if (!tti || !tti['extendedInfo'])
533 return;
534
535 var navStart = fmp['extendedInfo']['value']['timestamps']['navStart'];
536 var markers = [
537 {
538 title: Common.UIString('First contentful paint'),
539 value: (fmp['extendedInfo']['value']['timestamps']['fCP'] - navStart) / 1000
540 },
541 {
542 title: Common.UIString('First meaningful paint'),
543 value: (fmp['extendedInfo']['value']['timestamps']['fMP'] - navStart) / 1000
544 },
545 {
546 title: Common.UIString('Time to interactive'),
547 value: (tti['extendedInfo']['value']['timestamps']['timeToInteractive'] - navStart) / 1000
548 },
549 {
550 title: Common.UIString('Visually ready'),
551 value: (tti['extendedInfo']['value']['timestamps']['visuallyReady'] - na vStart) / 1000
552 }
553 ];
554
555 var screenshots = tracePass.traceEvents.filter(e => e.cat === 'disabled-by-d efault-devtools.screenshot');
556 var timelineElement = createElementWithClass('div', 'audits2-timeline');
557 var filmStripElement = timelineElement.createChild('div', 'audits2-filmstrip ');
558 var lastEvent = screenshots.peekLast();
559
560 var numberOfFrames = 8 + 1;
561 var roundToFraction = 4;
562 var timeSpan = (lastEvent.ts - navStart) / 1000;
563 var timeStep = (Math.ceil(timeSpan / numberOfFrames * roundToFraction / 1000 )) / roundToFraction * 1000;
564
565 for (var time = timeStep; time <= timeSpan; time += timeStep) {
paulirish 2017/05/04 23:06:31 a single screenshot trace will be a problem here.
566 var frameForTime = null;
567 for (var e of screenshots) {
568 if ((e.ts - navStart) / 1000 < time)
569 frameForTime = e.args.snapshot;
570 }
571 if (!frameForTime)
paulirish 2017/05/04 23:06:31 we'll want empty frames at the start if the first
572 continue;
573 var frame = filmStripElement.createChild('div', 'frame');
574 frame.createChild('div', 'time').textContent = Number.millisToString(time) ;
575 var img = frame.createChild('div', 'thumbnail').createChild('img');
576 img.src = 'data:image/jpg;base64,' + frameForTime;
577 }
578
579 for (var marker of markers) {
580 var markerElement = timelineElement.createChild('div', 'audits2-timeline-m arker');
581 markerElement.createChild('div', 'audits2-timeline-bar').style.width =
582 (100 * (marker.value / timeSpan) | 0) + '%';
583 markerElement.createChild('span').textContent = Common.UIString('%s: ', ma rker.title);
584 markerElement.createChild('span', 'audits2-timeline-subtitle').textContent = Number.millisToString(marker.value);
585 }
586
587 performanceScoreElement.parentElement.insertBefore(timelineElement, performa nceScoreElement.nextSibling);
517 } 588 }
518 }; 589 };
519 590
520 Audits2.Audits2Panel.TreeSubElement = class extends UI.TreeElement { 591 Audits2.Audits2Panel.TreeSubElement = class extends UI.TreeElement {
521 /** 592 /**
522 * @param {string} id 593 * @param {string} id
523 * @param {string} name 594 * @param {string} name
524 * @param {number} score 595 * @param {number} score
525 */ 596 */
526 constructor(id, name, score) { 597 constructor(id, name, score) {
(...skipping 12 matching lines...) Expand all
539 onselect() { 610 onselect() {
540 this.parent._renderReport(); 611 this.parent._renderReport();
541 var node = this.parent._resultsView.querySelector('.lh-category[id=' + this. _id + ']'); 612 var node = this.parent._resultsView.querySelector('.lh-category[id=' + this. _id + ']');
542 if (node) { 613 if (node) {
543 node.scrollIntoView(true); 614 node.scrollIntoView(true);
544 return true; 615 return true;
545 } 616 }
546 return false; 617 return false;
547 } 618 }
548 }; 619 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698