-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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: add no-unload-listeners audit #11085
Conversation
/** Descriptive title of a Lighthouse audit that checks if a web page has 'unload' event listeners and finds that it is using them. */ | ||
failureTitle: 'Listens for the `unload` event', | ||
/** Description of a Lighthouse audit that tells the user why pages should not use the 'unload' event. This is displayed after a user expands the section to see more. 'Learn More' becomes link text to additional documentation. */ | ||
description: 'The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the back/forward cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn More](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#legacy-lifecycle-apis-to-avoid)', |
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.
url will be updated when we have an article
/** @type {LH.Audit.Details.Table['items']} */ | ||
const tableItems = unloadListeners.map(listener => { | ||
// Look up scriptId to script URL via the JsUsage artifact. | ||
const usageEntry = jsUsageValues.find(usage => usage.scriptId === listener.scriptId); |
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.
The protocol doesn't give script URLs for event listeners, just scriptIds, so JsUsage
seemed like the best place to get the mapping.
const {result: {objectId}} = await driver.sendCommand('Runtime.evaluate', { | ||
expression: 'window', | ||
returnByValue: false, | ||
}); |
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.
if anyone has an easier way of getting window
's RemoteObjectId
, please let me know :)
return listener.type === 'pagehide' || | ||
listener.type === 'unload' || | ||
listener.type === 'visibilitychange'; |
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.
as mentioned in the PR description, this can go back to just unload
before landing, but there may be more analysis that we can do with these so leaving it like this for now
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.
seems like this could be upgraded to non-draft, nothing showstopping here looks good to me 👍
switched to |
done and done |
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.
a basic unit test for the audit linking up the script ID to the network would be nice
LGTM otherwise 🎉
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.
a basic unit test for the audit linking up the script ID to the network would be nice
yes, definitely, in progress :)
/** Descriptive title of a Lighthouse audit that checks if a web page has 'unload' event listeners and finds that it is using them. */ | ||
failureTitle: 'Listens for the `unload` event', | ||
/** Description of a Lighthouse audit that tells the user why pages should not use the 'unload' event. This is displayed after a user expands the section to see more. 'Learn More' becomes link text to additional documentation. */ | ||
description: 'The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the back/forward cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn More](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)', |
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.
description: 'The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the back/forward cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn More](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)', | |
description: 'The `unload` event does not fire reliably and listening for it prevents browser optimizations like the back/forward cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn More](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)', |
?
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.
wellllll, that may be complicated :) I'll wait for @philipwalton and others to come weigh in on everything and we can nail down the exact wording all at once
152b438
to
7558d39
Compare
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.
LGTM
@@ -552,6 +554,7 @@ const defaultConfig = { | |||
{id: 'doctype', weight: 1, group: 'best-practices-browser-compat'}, | |||
{id: 'charset', weight: 1, group: 'best-practices-browser-compat'}, | |||
// General Group | |||
{id: 'no-unload-listeners', weight: 1, group: 'best-practices-general'}, |
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.
feels like it could be a diagnostic too, any particular decision insights behind best practices we can leave for future git blame archeologists? :)
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.
feels like it could be a diagnostic too, any particular decision insights behind best practices we can leave for future git blame archeologists? :)
I guess it kind of falls in with uses-long-cache-ttl
as something diagnosing performance, just not the performance of any of the metrics just measured (since a Lighthouse run isn't (usually) with a warm cache or on a hit of the back button). I guess I could see the argument that it's still worthwhile to have there, but I chose this as the uncontroversial spot to put it. I don't feel strongly :)
return listeners | ||
.filter(GlobalListeners._filterForUnloadTypes) | ||
.map(listener => { | ||
const {type, scriptId, lineNumber, columnNumber} = listener; |
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'm just noticing this is already back in node-land so serialization isn't the reason for reexposing, just trying to limit what we return?
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.
just trying to limit what we return?
yeah
/** Descriptive title of a Lighthouse audit that checks if a web page has 'unload' event listeners and finds that it is using them. */ | ||
failureTitle: 'Listens for the `unload` event', | ||
/** Description of a Lighthouse audit that tells the user why pages should not use the 'unload' event. This is displayed after a user expands the section to see more. 'Learn More' becomes link text to additional documentation. */ | ||
description: 'The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the back/forward cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn More](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)', |
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.
https://webkit.org/blog/427/webkit-page-cache-i-the-basics/ and https://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ cover it as well. also shout out to Dojo for addressing this audit 11 years ago. :)
/** Descriptive title of a Lighthouse audit that checks if a web page has 'unload' event listeners and finds none. */ | ||
title: 'Avoids `unload` event listeners', | ||
/** Descriptive title of a Lighthouse audit that checks if a web page has 'unload' event listeners and finds that it is using them. */ | ||
failureTitle: 'Listens for the `unload` event', |
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.
Alt wording would be "Registers an unload
listener". I like it a tad more, but, not a huge deal.
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.
Alt wording would be "Registers an
unload
listener". I like it a tad more, but, not a huge deal.
I guess it's technically still true, but a little awkward when the page registers multiple unload listeners (plural).
0549f57
to
e5685e1
Compare
ref GoogleChrome/web-vitals#68 won't fail the new [`no-unload-listeners`](GoogleChrome/lighthouse#11085) Lighthouse audit.
ref GoogleChrome/web-vitals#68 won't fail the new [`no-unload-listeners`](GoogleChrome/lighthouse#11085) Lighthouse audit.
Fixes #10848.
WIP for nowAll should feel free to comment on the details to highlight and advice the audit should provide.Right now the audit fails if any
'unload'
listener is registered, and recommends using'pagehide'
or'visibilitychange'
instead (leaving it up to the (eventually) linked docs to explain which of the two you might choose to use). The audit table isjust using the plain old violations-style tableusingsource-location
, happy to iterate:live example:
https://googlechrome.github.io/lighthouse/viewer/?gist=12c8d8d522e867564a4c3a526f4981bd
old example
live example (scroll down to Best Practices)
https://googlechrome.github.io/lighthouse/viewer/?gist=aeb90c472c6c079e0429faf370bb83b1
for the new gatherer, this information didn't really fit into an existing one, and I didn't really want to open us up to just collecting all the event listeners, so I kept it somewhat narrow in scope. I did include other unload-adjacent events because I get the feeling from talking to @philipwalton that there is more analysis we can do here about bfcache-worthiness, but if that doesn't materialize I can also narrow it down even more. I'm also open to completely different ideas :)