-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core(lightwallet): add resource-summary audit #8522
Merged
brendankenny
merged 7 commits into
GoogleChrome:master
from
khempenius:lw_resources_audit
May 1, 2019
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
51d7a40
Add resource-summary audit
khempenius b1404da
Merge branch 'master' of https://github.com/GoogleChrome/lighthouse i…
khempenius 7ba2fb2
lightwallet: add gray circle styling for info audits
khempenius f8e5177
lightwallet: update test artifacts; mv some strings to shared
khempenius fae0051
lightwallet: Third-party should be last table row
khempenius 838060c
lightwallet: rm diagnostic styling code
khempenius 2ee8053
LightWallet: more changes to resource-summary audit
khempenius File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* @license Copyright 2019 Google Inc. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. | ||
*/ | ||
'use strict'; | ||
|
||
const Audit = require('./audit.js'); | ||
const ComputedResourceSummary = require('../computed/resource-summary.js'); | ||
const i18n = require('../lib/i18n/i18n.js'); | ||
|
||
const UIStrings = { | ||
/** Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page. */ | ||
title: 'Keep request counts low and transfer sizes small', | ||
/** Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits. */ | ||
description: 'To set budgets for the quantity and size of page resources,' + | ||
' add a budget.json file.', | ||
/** [ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page. */ | ||
displayValue: `{requestCount, plural, =1 {1 request} other {# requests}}` + | ||
` • { byteCount, number, bytes } KB`, | ||
}; | ||
|
||
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); | ||
|
||
class ResourceSummary extends Audit { | ||
/** | ||
* @return {LH.Audit.Meta} | ||
*/ | ||
static get meta() { | ||
return { | ||
id: 'resource-summary', | ||
title: str_(UIStrings.title), | ||
description: str_(UIStrings.description), | ||
scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, | ||
khempenius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
requiredArtifacts: ['devtoolsLogs', 'URL'], | ||
}; | ||
} | ||
|
||
/** | ||
* @param {LH.Artifacts} artifacts | ||
* @param {LH.Audit.Context} context | ||
* @return {Promise<LH.Audit.Product>} | ||
*/ | ||
static async audit(artifacts, context) { | ||
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS]; | ||
const summary = await ComputedResourceSummary | ||
.request({devtoolsLog, URL: artifacts.URL}, context); | ||
|
||
/** @type {LH.Audit.Details.Table['headings']} */ | ||
const headings = [ | ||
{key: 'label', itemType: 'text', text: 'Resource Type'}, | ||
{key: 'requestCount', itemType: 'numeric', text: 'Requests'}, | ||
{key: 'size', itemType: 'bytes', text: 'Transfer Size'}, | ||
]; | ||
|
||
|
||
/** @type {Record<LH.Budget.ResourceType,string>} */ | ||
const strMappings = { | ||
khempenius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'total': str_(i18n.UIStrings.totalResourceType), | ||
'document': str_(i18n.UIStrings.documentResourceType), | ||
'script': str_(i18n.UIStrings.scriptResourceType), | ||
'stylesheet': str_(i18n.UIStrings.stylesheetResourceType), | ||
'image': str_(i18n.UIStrings.imageResourceType), | ||
'media': str_(i18n.UIStrings.mediaResourceType), | ||
'font': str_(i18n.UIStrings.fontResourceType), | ||
'other': str_(i18n.UIStrings.otherResourceType), | ||
'third-party': str_(i18n.UIStrings.thirdPartyResourceType), | ||
}; | ||
|
||
const types = /** @type {Array<LH.Budget.ResourceType>} */ (Object.keys(summary)); | ||
const rows = types.map(type => { | ||
return { | ||
// ResourceType is included as an "id" for ease of use. | ||
// It does not appear directly in the table. | ||
resourceType: type, | ||
label: strMappings[type], | ||
requestCount: summary[type].count, | ||
size: summary[type].size, | ||
}; | ||
}); | ||
// Force third-party to be last, descending by size otherwise | ||
const thirdPartyRow = rows.find(r => r.resourceType === 'third-party') || []; | ||
khempenius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const otherRows = rows.filter(r => r.resourceType !== 'third-party') | ||
.sort((a, b) => { | ||
return b.size - a.size; | ||
}); | ||
const tableItems = otherRows.concat(thirdPartyRow); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❤️ |
||
|
||
const tableDetails = Audit.makeTableDetails(headings, tableItems); | ||
|
||
return { | ||
details: tableDetails, | ||
score: 1, | ||
displayValue: str_(UIStrings.displayValue, { | ||
requestCount: summary.total.count, | ||
byteCount: summary.total.size, | ||
}), | ||
}; | ||
} | ||
} | ||
|
||
module.exports = ResourceSummary; | ||
module.exports.UIStrings = UIStrings; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/** | ||
* @license Copyright 2019 Google Inc. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. | ||
*/ | ||
'use strict'; | ||
|
||
const ResourceSummaryAudit = require('../../audits/resource-summary.js'); | ||
const networkRecordsToDevtoolsLog = require('../network-records-to-devtools-log.js'); | ||
khempenius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/* eslint-env jest */ | ||
|
||
describe('Performance: Resource summary audit', () => { | ||
let artifacts; | ||
let context; | ||
beforeEach(() => { | ||
context = {computedCache: new Map()}; | ||
|
||
artifacts = { | ||
devtoolsLogs: { | ||
defaultPass: networkRecordsToDevtoolsLog([ | ||
{url: 'http://example.com/file.html', resourceType: 'Document', transferSize: 30}, | ||
{url: 'http://example.com/app.js', resourceType: 'Script', transferSize: 10}, | ||
{url: 'http://third-party.com/script.js', resourceType: 'Script', transferSize: 50}, | ||
{url: 'http://third-party.com/file.jpg', resourceType: 'Image', transferSize: 70}, | ||
])}, | ||
URL: {requestedUrl: 'https://example.com', finalUrl: 'https://example.com'}, | ||
}; | ||
}); | ||
|
||
khempenius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
it('has three table columns', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
expect(result.details.headings).toHaveLength(3); | ||
}); | ||
|
||
it('has the correct score', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
expect(result.score).toBe(1); | ||
}); | ||
|
||
it('has the correct display value', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
expect(result.displayValue).toBeDisplayString('4 requests • 0 KB'); | ||
}); | ||
|
||
it('includes the correct properties for each table item', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
const item = result.details.items[0]; | ||
expect(item.resourceType).toEqual('total'); | ||
expect(item.label).toBeDisplayString('Total'); | ||
expect(item.requestCount).toBe(4); | ||
expect(item.size).toBe(160); | ||
}); | ||
|
||
it('includes all resource types, regardless of whether page contains them', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
expect(Object.keys(result.details.items)).toHaveLength(9); | ||
}); | ||
|
||
it('it displays "0" if there are no resources of that type', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
const fontItem = result.details.items.find(item => item.resourceType === 'font'); | ||
expect(fontItem.requestCount).toBe(0); | ||
expect(fontItem.size).toBe(0); | ||
}); | ||
|
||
describe('table ordering', () => { | ||
it('except for the last row, it sorts items by size (descending)', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
const items = result.details.items; | ||
khempenius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
items.slice(0, -2).forEach((item, index) => { | ||
expect(item.size).toBeGreaterThanOrEqual(items[index + 1].size); | ||
}); | ||
}); | ||
|
||
it('"Total" is the first row', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
expect(result.details.items[0].resourceType).toBe('total'); | ||
}); | ||
|
||
it('"Third-party" is the last-row', async () => { | ||
const result = await ResourceSummaryAudit.audit(artifacts, context); | ||
const items = result.details.items; | ||
expect(items[items.length - 1].resourceType).toBe('third-party'); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry if I already said this but are we gonna link this up to a doc? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was planning on doing that in a separate PR once we know where that lives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also added it to #8331 in the lightwallet section