Skip to content

Commit 97c7170

Browse files
committed
Report: improvements w/ new density... (#2706)
category hash nav shouldn't underlap the fixed header firefox support width@964 breakpoint. fix @print styles: show site URL & time ensmallen scorecards. size based off body-font-size shorter sparklines. for perf opportunities, show debugText within summary, so it isn't pushed below large results tables. break-word for long urls in debugStrings sharper focus ring 5px -> 3px open details by default some groups can't be collapsed: failed, perf groups, a11y failing no special styling for the manual section devtools font size isn't smaller than 12px
1 parent a9867d5 commit 97c7170

File tree

6 files changed

+107
-116
lines changed

6 files changed

+107
-116
lines changed

lighthouse-core/report/v2/renderer/category-renderer.js

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ class CategoryRenderer {
163163
const titleEl = this._dom.createChildOf(summary, 'div', 'lh-perf-hint__title');
164164
titleEl.textContent = audit.result.description;
165165

166+
this._dom.createChildOf(summary, 'div', 'lh-toggle-arrow', {title: 'See resources'});
167+
166168
if (!extendedInfo || typeof audit.result.rawValue !== 'number') {
167169
const debugStrEl = this._dom.createChildOf(summary, 'div', 'lh-debug');
168170
debugStrEl.textContent = audit.result.debugString || 'Report error: no extended information';
@@ -179,8 +181,6 @@ class CategoryRenderer {
179181
const statsMsEl = this._dom.createChildOf(statsEl, 'div', 'lh-perf-hint__primary-stat');
180182
statsMsEl.textContent = Util.formatMilliseconds(audit.result.rawValue);
181183

182-
this._dom.createChildOf(summary, 'div', 'lh-toggle-arrow', {title: 'See resources'});
183-
184184
if (extendedInfo.value.wastedKb) {
185185
const statsKbEl = this._dom.createChildOf(statsEl, 'div', 'lh-perf-hint__secondary-stat');
186186
statsKbEl.textContent = Util.formatNumber(extendedInfo.value.wastedKb) + ' KB';
@@ -190,9 +190,8 @@ class CategoryRenderer {
190190
descriptionEl.appendChild(this._dom.convertMarkdownLinkSnippets(audit.result.helpText));
191191

192192
if (audit.result.debugString) {
193-
const debugStrEl = this._dom.createChildOf(element, 'div', 'lh-debug');
193+
const debugStrEl = this._dom.createChildOf(summary, 'div', 'lh-debug');
194194
debugStrEl.textContent = audit.result.debugString;
195-
element.open = true;
196195
}
197196

198197
if (audit.result.details) {
@@ -206,31 +205,27 @@ class CategoryRenderer {
206205
* Renders the group container for a group of audits. Individual audit elements can be added
207206
* directly to the returned element.
208207
* @param {!ReportRenderer.GroupJSON} group
209-
* @return {!HTMLDetailsElement}
208+
* @param {{expandable: boolean}} opts
209+
* @return {!Element}
210210
*/
211-
_renderAuditGroup(group) {
212-
const auditGroupElem = /** @type {!HTMLDetailsElement} */ (this._dom.createElement('details',
213-
'lh-audit-group lh-expandable-details'));
214-
const auditGroupHeader = this._dom.createElement('div',
215-
'lh-audit-group__header lh-expandable-details__header');
216-
auditGroupHeader.textContent = group.title;
217-
218-
const auditGroupSummary = this._dom.createElement('summary',
219-
'lh-audit-group__summary lh-expandable-details__summary');
220-
const auditGroupArrow = this._dom.createElement('div', 'lh-toggle-arrow', {
221-
title: 'See audits',
222-
});
223-
auditGroupSummary.appendChild(auditGroupHeader);
224-
auditGroupSummary.appendChild(auditGroupArrow);
225-
auditGroupElem.appendChild(auditGroupSummary);
211+
_renderAuditGroup(group, opts) {
212+
const expandable = opts.expandable;
213+
const element = this._dom.createElement(expandable ? 'details' :'div', 'lh-audit-group');
214+
const summmaryEl = this._dom.createChildOf(element, 'summary', 'lh-audit-group__summary');
215+
const headerEl = this._dom.createChildOf(summmaryEl, 'div', 'lh-audit-group__header');
216+
this._dom.createChildOf(summmaryEl, 'div',
217+
`lh-toggle-arrow ${expandable ? '' : ' lh-toggle-arrow-unexpandable'}`, {
218+
title: 'See audits',
219+
});
226220

227221
if (group.description) {
228222
const auditGroupDescription = this._dom.createElement('div', 'lh-audit-group__description');
229223
auditGroupDescription.appendChild(this._dom.convertMarkdownLinkSnippets(group.description));
230-
auditGroupElem.appendChild(auditGroupDescription);
224+
element.appendChild(auditGroupDescription);
231225
}
226+
headerEl.textContent = group.title;
232227

233-
return auditGroupElem;
228+
return element;
234229
}
235230

236231
/**
@@ -240,7 +235,7 @@ class CategoryRenderer {
240235
_renderPassedAuditsSection(elements) {
241236
const passedElem = this._renderAuditGroup({
242237
title: `${elements.length} Passed Audits`,
243-
});
238+
}, {expandable: true});
244239
passedElem.classList.add('lh-passed-audits');
245240
elements.forEach(elem => passedElem.appendChild(elem));
246241
return passedElem;
@@ -262,7 +257,7 @@ class CategoryRenderer {
262257

263258
Object.keys(auditsGroupedByGroup).forEach(groupId => {
264259
const group = groupDefinitions[groupId];
265-
const auditGroupElem = this._renderAuditGroup(group);
260+
const auditGroupElem = this._renderAuditGroup(group, {expandable: true});
266261
auditGroupElem.classList.add('lh-audit-group--manual');
267262

268263
auditsGroupedByGroup[groupId].forEach(audit => {
@@ -333,7 +328,7 @@ class CategoryRenderer {
333328
*/
334329
_renderDefaultCategory(category, groupDefinitions) {
335330
const element = this._dom.createElement('div', 'lh-category');
336-
element.id = category.id;
331+
this._createPermalinkSpan(element, category.id);
337332
element.appendChild(this._renderCategoryScore(category));
338333

339334
const manualAudits = category.audits.filter(audit => audit.result.manual);
@@ -344,8 +339,8 @@ class CategoryRenderer {
344339

345340
const nonPassedElem = this._renderAuditGroup({
346341
title: `${nonPassedAudits.length} failed audits`,
347-
});
348-
nonPassedElem.open = true;
342+
}, {expandable: false});
343+
nonPassedElem.classList.add('lh-failed-audits');
349344
nonPassedAudits.forEach(audit => nonPassedElem.appendChild(this._renderAudit(audit)));
350345
element.appendChild(nonPassedElem);
351346

@@ -370,11 +365,11 @@ class CategoryRenderer {
370365
*/
371366
_renderPerformanceCategory(category, groups) {
372367
const element = this._dom.createElement('div', 'lh-category');
373-
element.id = category.id;
368+
this._createPermalinkSpan(element, category.id);
374369
element.appendChild(this._renderCategoryScore(category));
375370

376371
const metricAudits = category.audits.filter(audit => audit.group === 'perf-metric');
377-
const metricAuditsEl = this._renderAuditGroup(groups['perf-metric']);
372+
const metricAuditsEl = this._renderAuditGroup(groups['perf-metric'], {expandable: false});
378373
const timelineContainerEl = this._dom.createChildOf(metricAuditsEl, 'div',
379374
'lh-timeline-container');
380375
const timelineEl = this._dom.createChildOf(timelineContainerEl, 'div', 'lh-timeline');
@@ -413,7 +408,7 @@ class CategoryRenderer {
413408
if (hintAudits.length) {
414409
const maxWaste = Math.max(...hintAudits.map(audit => audit.result.rawValue));
415410
const scale = Math.ceil(maxWaste / 1000) * 1000;
416-
const hintAuditsEl = this._renderAuditGroup(groups['perf-hint']);
411+
const hintAuditsEl = this._renderAuditGroup(groups['perf-hint'], {expandable: false});
417412
hintAudits.forEach(item => hintAuditsEl.appendChild(this._renderPerfHintAudit(item, scale)));
418413
hintAuditsEl.open = true;
419414
element.appendChild(hintAuditsEl);
@@ -422,7 +417,7 @@ class CategoryRenderer {
422417
const infoAudits = category.audits
423418
.filter(audit => audit.group === 'perf-info' && audit.score < 100);
424419
if (infoAudits.length) {
425-
const infoAuditsEl = this._renderAuditGroup(groups['perf-info']);
420+
const infoAuditsEl = this._renderAuditGroup(groups['perf-info'], {expandable: false});
426421
infoAudits.forEach(item => infoAuditsEl.appendChild(this._renderAudit(item)));
427422
infoAuditsEl.open = true;
428423
element.appendChild(infoAuditsEl);
@@ -447,7 +442,7 @@ class CategoryRenderer {
447442
*/
448443
_renderAccessibilityCategory(category, groupDefinitions) {
449444
const element = this._dom.createElement('div', 'lh-category');
450-
element.id = category.id;
445+
this._createPermalinkSpan(element, category.id);
451446
element.appendChild(this._renderCategoryScore(category));
452447

453448
const auditsGroupedByGroup = /** @type {!Object<string,
@@ -471,14 +466,14 @@ class CategoryRenderer {
471466
const group = groupDefinitions[groupId];
472467
const groups = auditsGroupedByGroup[groupId];
473468
if (groups.failed.length) {
474-
const auditGroupElem = this._renderAuditGroup(group);
469+
const auditGroupElem = this._renderAuditGroup(group, {expandable: false});
475470
groups.failed.forEach(item => auditGroupElem.appendChild(this._renderAudit(item)));
476471
auditGroupElem.open = true;
477472
element.appendChild(auditGroupElem);
478473
}
479474

480475
if (groups.passed.length) {
481-
const auditGroupElem = this._renderAuditGroup(group);
476+
const auditGroupElem = this._renderAuditGroup(group, {expandable: true});
482477
groups.passed.forEach(item => auditGroupElem.appendChild(this._renderAudit(item)));
483478
passedElements.push(auditGroupElem);
484479
}
@@ -491,6 +486,16 @@ class CategoryRenderer {
491486
element.appendChild(passedElem);
492487
return element;
493488
}
489+
490+
/**
491+
* Create a non-semantic span used for hash navigation of categories
492+
* @param {!Element} element
493+
* @param {string} id
494+
*/
495+
_createPermalinkSpan(element, id) {
496+
const permalinkEl = this._dom.createChildOf(element, 'span', 'lh-permalink');
497+
permalinkEl.id = id;
498+
}
494499
}
495500

496501
if (typeof module !== 'undefined' && module.exports) {

lighthouse-core/report/v2/renderer/crc-details-renderer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class CriticalRequestChainRenderer {
161161
Util.formatBytesToKB(details.longestChain.transferSize);
162162

163163
const detailsEl = dom.find('.lh-details', tmpl);
164+
detailsEl.open = true;
164165

165166
dom.find('.lh-details > summary', tmpl).textContent = details.header.text;
166167

lighthouse-core/report/v2/renderer/details-renderer.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class DetailsRenderer {
125125
if (!list.items.length) return this._dom.createElement('span');
126126

127127
const element = this._dom.createElement('details', 'lh-details');
128+
element.open = true;
128129
if (list.header) {
129130
const summary = this._dom.createElement('summary', 'lh-list__header');
130131
summary.textContent = list.header.text;
@@ -147,6 +148,7 @@ class DetailsRenderer {
147148
if (!details.items.length) return this._dom.createElement('span');
148149

149150
const element = this._dom.createElement('details', 'lh-details');
151+
element.open = true;
150152
if (details.header) {
151153
element.appendChild(this._dom.createElement('summary')).textContent = details.header;
152154
}
@@ -194,6 +196,7 @@ class DetailsRenderer {
194196
*/
195197
_renderCards(details) {
196198
const element = this._dom.createElement('details', 'lh-details');
199+
element.open = true;
197200
if (details.header) {
198201
element.appendChild(this._dom.createElement('summary')).textContent = details.header.text;
199202
}

0 commit comments

Comments
 (0)