-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
new_audit: offline-start-url #6397
Changes from all commits
33a6227
b341a99
46a1b9a
788ca28
326952e
c3c0a4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* @license Copyright 2018 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'); | ||
|
||
class OfflineStartUrl extends Audit { | ||
/** | ||
* @return {LH.Audit.Meta} | ||
*/ | ||
static get meta() { | ||
return { | ||
id: 'offline-start-url', | ||
title: 'start_url responds with a 200 when offline', | ||
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. should we be trying to unrelated: 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.
I like doing them with everyone all at once so I can avoid responsibility for them, but should we do them as we go?
haha, I felt the same, but it felt worse to just have them be words. "Start URL responds with a 200..." 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. Maybe "Service Worker's start_url responds with a 200"? 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.
yeah, it's not the service worker's 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. There's a text update on the dunno if you want to do that here but we shouldn't drop it. 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.
The current proposed update is
|
||
failureTitle: 'start_url does not respond with a 200 when offline', | ||
description: 'A service worker enables your web app to be reliable in unpredictable network conditions. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline).', | ||
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. nit: I feel like this maybe isn't specific enough? Someone might have a service worker but have a bad start_url that would be flagged by this audit. "A service worker with a valid start_url enables your web app.." 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.
yeah, I'm just not sure how to word it. It's not the service worker that has the start_url, it's the manifest, though the service worker needs to serve it. Maybe we can tweak |
||
requiredArtifacts: ['Manifest', 'StartUrl'], | ||
}; | ||
} | ||
|
||
/** | ||
* @param {LH.Artifacts} artifacts | ||
* @return {LH.Audit.Product} | ||
*/ | ||
static audit(artifacts) { | ||
// StartUrl gatherer will give explanations for failures, but need to take manifest parsing | ||
// warnings from the manifest itself (e.g. invalid `start_url`, so fell back to document URL). | ||
const warnings = []; | ||
const manifest = artifacts.Manifest; | ||
if (manifest && manifest.value && manifest.value.start_url.warning) { | ||
const manifestWarning = manifest.value.start_url.warning; | ||
warnings.push('We couldn\'t read the start_url from the manifest. As a result, the ' + | ||
`start_url was assumed to be the document's URL. Error message: '${manifestWarning}'.`); | ||
} | ||
|
||
const hasOfflineStartUrl = artifacts.StartUrl.statusCode === 200; | ||
|
||
return { | ||
rawValue: hasOfflineStartUrl, | ||
explanation: artifacts.StartUrl.explanation, | ||
warnings, | ||
}; | ||
} | ||
} | ||
|
||
module.exports = OfflineStartUrl; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,6 +132,7 @@ const defaultConfig = { | |
'font-display', | ||
'network-requests', | ||
'metrics', | ||
'offline-start-url', | ||
'manual/pwa-cross-browser', | ||
'manual/pwa-page-transitions', | ||
'manual/pwa-each-page-has-url', | ||
|
@@ -334,10 +335,11 @@ const defaultConfig = { | |
// Fast and Reliable | ||
{id: 'load-fast-enough-for-pwa', weight: 7, group: 'pwa-fast-reliable'}, | ||
{id: 'works-offline', weight: 5, group: 'pwa-fast-reliable'}, | ||
{id: 'offline-start-url', weight: 1, group: 'pwa-fast-reliable'}, | ||
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. keeps the scores the same as before for now ( |
||
// Installable | ||
{id: 'is-on-https', weight: 2, group: 'pwa-installable'}, | ||
{id: 'service-worker', weight: 1, group: 'pwa-installable'}, | ||
{id: 'webapp-install-banner', weight: 3, group: 'pwa-installable'}, | ||
{id: 'webapp-install-banner', weight: 2, group: 'pwa-installable'}, | ||
// Engaging | ||
{id: 'redirects-http', weight: 2, group: 'pwa-engaging'}, | ||
{id: 'splash-screen', weight: 1, group: 'pwa-engaging'}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,8 @@ | |
|
||
const Gatherer = require('./gatherer'); | ||
const manifestParser = require('../../lib/manifest-parser'); | ||
const Driver = require('../driver.js'); // eslint-disable-line no-unused-vars | ||
|
||
/** @typedef {import('../driver.js')} Driver */ | ||
|
||
class StartUrl extends Gatherer { | ||
/** | ||
|
@@ -29,33 +30,27 @@ class StartUrl extends Gatherer { | |
|
||
return this._attemptManifestFetch(passContext.driver, startUrlInfo.startUrl); | ||
}).catch(() => { | ||
return {statusCode: -1, explanation: 'Unable to fetch start URL via service worker'}; | ||
return {statusCode: -1, explanation: 'Unable to fetch start URL via service worker.'}; | ||
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. periods added to look better in the report :) (this is currently the only audit using this gatherer) |
||
}); | ||
} | ||
|
||
/** | ||
* Read the parsed manifest and return failure reasons or the startUrl | ||
* @param {?{value?: {start_url: {value?: string, warning?: string}}, warning?: string}} manifest | ||
* @param {?{value?: {start_url: {value: string, warning?: string}}, warning?: string}} manifest | ||
* @return {{isReadFailure: true, reason: string}|{isReadFailure: false, startUrl: string}} | ||
*/ | ||
_readManifestStartUrl(manifest) { | ||
if (!manifest || !manifest.value) { | ||
const detailedMsg = manifest && manifest.warning; | ||
|
||
if (detailedMsg) { | ||
return {isReadFailure: true, reason: `Error fetching web app manifest: ${detailedMsg}`}; | ||
return {isReadFailure: true, reason: `Error fetching web app manifest: ${detailedMsg}.`}; | ||
} else { | ||
return {isReadFailure: true, reason: `No usable web app manifest found on page`}; | ||
return {isReadFailure: true, reason: `No usable web app manifest found on page.`}; | ||
} | ||
} | ||
|
||
// Even if the start URL had an error, the browser will still supply a fallback URL. | ||
// Therefore, we only set the warning here and continue with the fetch. | ||
if (manifest.value.start_url.warning) { | ||
return {isReadFailure: true, reason: manifest.value.start_url.warning}; | ||
} | ||
|
||
// @ts-ignore - TODO(bckenny): should actually be testing value above, not warning | ||
// Even if the start URL had a parser warning, the browser will still supply a fallback URL. | ||
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. this was wrong before. A manifest parsing warning doesn't mean there was a read failure, since the parser falls back to the document URL |
||
return {isReadFailure: false, startUrl: manifest.value.start_url.value}; | ||
} | ||
|
||
|
@@ -70,7 +65,7 @@ class StartUrl extends Gatherer { | |
// Wait up to 3s to get a matched network request from the fetch() to work | ||
const timeoutPromise = new Promise(resolve => | ||
setTimeout( | ||
() => resolve({statusCode: -1, explanation: 'Timed out waiting for fetched start_url'}), | ||
() => resolve({statusCode: -1, explanation: 'Timed out waiting for fetched start_url.'}), | ||
3000 | ||
) | ||
); | ||
|
@@ -88,7 +83,7 @@ class StartUrl extends Gatherer { | |
if (!response.fromServiceWorker) { | ||
return resolve({ | ||
statusCode: -1, | ||
explanation: 'Unable to fetch start URL via service worker', | ||
explanation: 'Unable to fetch start URL via service worker.', | ||
}); | ||
} | ||
// Successful SW-served fetch of the start_URL | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -115,6 +115,7 @@ function checkSameOrigin(url1, url2) { | |
* @param {*} jsonInput | ||
* @param {string} manifestUrl | ||
* @param {string} documentUrl | ||
* @return {{raw: any, value: string, warning?: string}} | ||
*/ | ||
function parseStartUrl(jsonInput, manifestUrl, documentUrl) { | ||
const raw = jsonInput.start_url; | ||
|
@@ -127,10 +128,18 @@ function parseStartUrl(jsonInput, manifestUrl, documentUrl) { | |
warning: 'ERROR: start_url string empty', | ||
}; | ||
} | ||
const parsedAsString = parseString(raw); | ||
if (!parsedAsString.value) { | ||
parsedAsString.value = documentUrl; | ||
return parsedAsString; | ||
if (raw === undefined) { | ||
return { | ||
raw, | ||
value: documentUrl, | ||
}; | ||
} | ||
if (typeof raw !== 'string') { | ||
return { | ||
raw, | ||
value: documentUrl, | ||
warning: 'ERROR: expected a string.', | ||
}; | ||
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. equivalent to before, but a lot easier to understand what happens to |
||
} | ||
|
||
// 8.10(4) - construct URL with raw as input and manifestUrl as the base. | ||
|
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.
webapp-install-banner
was the only one usingwarnings
for start_url warnings, so no longer needed