Skip to content

Commit

Permalink
Report v2: Basic table formatter (GoogleChrome#2019)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulirish committed May 5, 2017
1 parent 284c0ba commit 3e76e07
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 67 deletions.
77 changes: 77 additions & 0 deletions lighthouse-core/audits/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,65 @@ class Audit {
});
}

/**
* @param {!Audit.Headings} headings
* @return {!Array<string>}
*/
static makeV1TableHeadings(headings) {
const tableHeadings = {};
headings.forEach(heading => tableHeadings[heading.key] = heading.text);
return tableHeadings;
}

/**
* Table cells will use the type specified in headings[x].itemType. However a custom type
* can be provided: results[x].propName = {type: 'code', text: '...'}
* @param {!Audit.Headings} headings
* @param {!Array<!Object<string, *>>} results
* @return {!Array<!DetailsRenderer.DetailsJSON>}
*/
static makeV2TableRows(headings, results) {
const tableRows = results.map(item => {
return headings.map(heading => {
const value = item[heading.key];
if (typeof value === 'object' && value.type) return value;

return {
type: heading.itemType,
text: value
};
});
});
return tableRows;
}

/**
* @param {!Audit.Headings} headings
* @return {!Array<!DetailsRenderer.DetailsJSON>}
*/
static makeV2TableHeaders(headings) {
return headings.map(heading => ({
type: 'text',
text: heading.text
}));
}

/**
* @param {!Audit.Headings} headings
* @param {!Array<!Object<string, string>>} results
* @return {!DetailsRenderer.DetailsJSON}
*/
static makeV2TableDetails(headings, results) {
const v2TableHeaders = Audit.makeV2TableHeaders(headings);
const v2TableRows = Audit.makeV2TableRows(headings, results);
return {
type: 'table',
header: 'View Details',
itemHeaders: v2TableHeaders,
items: v2TableRows
};
}

/**
* @param {!Audit} audit
* @param {!AuditResult} result
Expand Down Expand Up @@ -97,3 +156,21 @@ class Audit {
}

module.exports = Audit;

/** @typedef {
* !Array<{
* key: string,
* itemType: string,
* text: string,
* }>}
*/
Audit.Headings; // eslint-disable-line no-unused-expressions

/** @typedef {{
* results: !Array<!Object<string, string>>,
* headings: !Audit.Headings,
* passes: boolean,
* debugString: (string|undefined)
* }}
*/
Audit.HeadingsResult; // eslint-disable-line no-unused-expressions
11 changes: 7 additions & 4 deletions lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ class UnusedBytes extends Audit {
}

/**
* @param {!{debugString: string=, passes: boolean=, tableHeadings: !Object,
* results: !Array<!Object>}} result
* @param {!Audit.HeadingsResult} result
* @param {number} networkThroughput
* @return {!AuditResult}
*/
Expand All @@ -98,6 +97,9 @@ class UnusedBytes extends Audit {
displayValue = `Potential savings of ${wastedKbDisplay} (~${wastedMsDisplay})`;
}

const v1TableHeadings = Audit.makeV1TableHeadings(result.headings);
const v2TableDetails = Audit.makeV2TableDetails(result.headings, results);

return {
debugString,
displayValue,
Expand All @@ -106,8 +108,9 @@ class UnusedBytes extends Audit {
!!result.passes,
extendedInfo: {
formatter: Formatter.SUPPORTED_FORMATS.TABLE,
value: {results, tableHeadings: result.tableHeadings}
}
value: {results, tableHeadings: v1TableHeadings}
},
details: v2TableDetails
};
}

Expand Down
19 changes: 11 additions & 8 deletions lighthouse-core/audits/byte-efficiency/offscreen-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
return {
url,
preview: {
type: 'thumbnail',
url: image.networkRecord.url,
mimeType: image.networkRecord.mimeType
},
Expand All @@ -95,8 +96,7 @@ class OffscreenImages extends ByteEfficiencyAudit {

/**
* @param {!Artifacts} artifacts
* @return {{results: !Array<Object>, tableHeadings: Object,
* passes: boolean=, debugString: string=}}
* @return {!Audit.HeadingsResult}
*/
static audit_(artifacts) {
const images = artifacts.ImageUsage;
Expand Down Expand Up @@ -132,15 +132,18 @@ class OffscreenImages extends ByteEfficiencyAudit {
const loadedEarly = item.requestStartTime < ttiTimestamp;
return isWasteful && loadedEarly;
});

const headings = [
{key: 'preview', itemType: 'thumbnail', text: ''},
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'totalKb', itemType: 'text', text: 'Original'},
{key: 'potentialSavings', itemType: 'text', text: 'Potential Savings'},
];

return {
debugString,
results,
tableHeadings: {
preview: '',
url: 'URL',
totalKb: 'Original',
potentialSavings: 'Potential Savings',
}
headings,
};
});
}
Expand Down
18 changes: 12 additions & 6 deletions lighthouse-core/audits/byte-efficiency/total-byte-weight.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ class TotalByteWeight extends ByteEfficiencyAudit {
SCORING_MEDIAN, SCORING_POINT_OF_DIMINISHING_RETURNS);
const score = 100 * distribution.computeComplementaryPercentile(totalBytes);

const headings = [
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'totalKb', itemType: 'text', text: 'Total Size'},
{key: 'totalMs', itemType: 'text', text: 'Transfer Time'},
];

const v1TableHeadings = ByteEfficiencyAudit.makeV1TableHeadings(headings);
const v2TableDetails = ByteEfficiencyAudit.makeV2TableDetails(headings, results);

return {
rawValue: totalBytes,
optimalValue: this.meta.optimalValue,
Expand All @@ -93,13 +102,10 @@ class TotalByteWeight extends ByteEfficiencyAudit {
formatter: Formatter.SUPPORTED_FORMATS.TABLE,
value: {
results,
tableHeadings: {
url: 'URL',
totalKb: 'Total Size',
totalMs: 'Transfer Time',
}
tableHeadings: v1TableHeadings
}
}
},
details: v2TableDetails
};
});
});
Expand Down
18 changes: 10 additions & 8 deletions lighthouse-core/audits/byte-efficiency/unused-css-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ class UnusedCSSRules extends ByteEfficiencyAudit {

/**
* @param {!Artifacts} artifacts
* @return {{results: !Array<Object>, tableHeadings: Object,
* passes: boolean=, debugString: string=}}
* @return {{results: !Array<Object>, headings: !Audit.Headings}}
*/
static audit_(artifacts) {
const styles = artifacts.Styles;
Expand All @@ -180,14 +179,17 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
return UnusedCSSRules.mapSheetToResult(indexedSheets[sheetId], pageUrl);
}).filter(sheet => sheet && sheet.wastedBytes > 1024);


const headings = [
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'numUnused', itemType: 'url', text: 'Unused Rules'},
{key: 'totalKb', itemType: 'text', text: 'Original'},
{key: 'potentialSavings', itemType: 'text', text: 'Potential Savings'},
];

return {
results,
tableHeadings: {
url: 'URL',
numUnused: 'Unused Rules',
totalKb: 'Original',
potentialSavings: 'Potential Savings',
}
headings
};
});
}
Expand Down
21 changes: 11 additions & 10 deletions lighthouse-core/audits/byte-efficiency/uses-optimized-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {

/**
* @param {!Artifacts} artifacts
* @return {{results: !Array<Object>, tableHeadings: Object,
* passes: boolean=, debugString: string=}}
* @return {!Audit.HeadingsResult}
*/
static audit_(artifacts) {
const images = artifacts.OptimizedImages;
Expand Down Expand Up @@ -106,7 +105,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
results.push({
url,
isCrossOrigin: !image.isSameOrigin,
preview: {url: image.url, mimeType: image.mimeType},
preview: {url: image.url, mimeType: image.mimeType, type: 'thumbnail'},
totalBytes: image.originalSize,
wastedBytes: webpSavings.bytes,
webpSavings: this.toSavingsString(webpSavings.bytes, webpSavings.percent),
Expand All @@ -121,17 +120,19 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
debugString = `Lighthouse was unable to decode some of your images: ${urls.join(', ')}`;
}

const headings = [
{key: 'preview', itemType: 'thumbnail', text: ''},
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'totalKb', itemType: 'text', text: 'Original'},
{key: 'webpSavings', itemType: 'text', text: 'Savings as WebP'},
{key: 'jpegSavings', itemType: 'text', text: 'Savings as JPEG'},
];

return {
passes: hasAllEfficientImages && totalWastedBytes < TOTAL_WASTED_BYTES_THRESHOLD,
debugString,
results,
tableHeadings: {
preview: '',
url: 'URL',
totalKb: 'Original',
webpSavings: 'WebP Savings',
jpegSavings: 'JPEG Savings',
}
headings
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit {
/**
* @param {!Artifacts} artifacts
* @param {number} networkThroughput
* @return {!AuditResult}
* @return {!Audit.HeadingsResult}
*/
static audit_(artifacts) {
const uncompressedResponses = artifacts.ResponseCompression;
Expand Down Expand Up @@ -90,15 +90,17 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit {
});

let debugString;
const headings = [
{key: 'url', itemType: 'url', text: 'Uncompressed resource URL'},
{key: 'totalKb', itemType: 'text', text: 'Original'},
{key: 'potentialSavings', itemType: 'text', text: 'GZIP Savings'},
];

return {
passes: totalWastedBytes < TOTAL_WASTED_BYTES_THRESHOLD,
debugString,
results,
tableHeadings: {
url: 'Uncompressed resource URL',
totalKb: 'Original',
potentialSavings: 'GZIP Savings',
}
headings,
};
}
}
Expand Down
19 changes: 11 additions & 8 deletions lighthouse-core/audits/byte-efficiency/uses-responsive-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
return {
url,
preview: {
type: 'thumbnail',
url: image.networkRecord.url,
mimeType: image.networkRecord.mimeType
},
Expand All @@ -80,8 +81,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {

/**
* @param {!Artifacts} artifacts
* @return {{results: !Array<Object>, tableHeadings: Object,
* passes: boolean=, debugString: string=}}
* @return {!Audit.HeadingsResult}
*/
static audit_(artifacts) {
const images = artifacts.ImageUsage;
Expand Down Expand Up @@ -111,16 +111,19 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {

const results = Array.from(resultsMap.values())
.filter(item => item.wastedBytes > IGNORE_THRESHOLD_IN_BYTES);

const headings = [
{key: 'preview', itemType: 'thumbnail', text: ''},
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'totalKb', itemType: 'text', text: 'Original'},
{key: 'potentialSavings', itemType: 'text', text: 'Potential Savings'},
];

return {
debugString,
passes: !results.find(item => item.isWasteful),
results,
tableHeadings: {
preview: '',
url: 'URL',
totalKb: 'Original',
potentialSavings: 'Potential Savings',
}
headings,
};
}
}
Expand Down
18 changes: 12 additions & 6 deletions lighthouse-core/audits/dobetterweb/link-blocking-first-paint.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,26 @@ class LinkBlockingFirstPaintAudit extends Audit {
displayValue = `${results.length} resource delayed first paint by ${delayTime}ms`;
}

const headings = [
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'totalKb', itemType: 'text', text: 'Size (KB)'},
{key: 'totalMs', itemType: 'text', text: 'Delayed Paint By (ms)'},
];

const v1TableHeadings = Audit.makeV1TableHeadings(headings);
const v2TableDetails = Audit.makeV2TableDetails(headings, results);

return {
displayValue,
rawValue: results.length === 0,
extendedInfo: {
formatter: Formatter.SUPPORTED_FORMATS.TABLE,
value: {
results,
tableHeadings: {
url: 'URL',
totalKb: 'Size (KB)',
totalMs: 'Delayed Paint By (ms)'
}
tableHeadings: v1TableHeadings
}
}
},
details: v2TableDetails
};
}

Expand Down
Loading

0 comments on commit 3e76e07

Please sign in to comment.