-
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
core(preconnect): add warning if preconnect link is not used #6694
Conversation
I actually like that we discard these records. Now your warning message isn't super helpful. If I read it I would add crossorigin to the preconnect tag and I'll see the same message pop up. Sometimes crossorigin helps but the urls listed in the bugs do not get fixed by slapping crossorigin on it. |
As in, you would like it if we started discarding ones started within the first 300 ms? :) Right now it's kinda strict at 50 ms.
Good point, should we not mention it at all then just save it for the docs? |
not sure what the correct timing is on this :) i'm fine with whatever is correct
Yes indeed, maybe just point out that the preconnect fields had no effect and refer to docs |
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.
Isn't #5932 pointing out we tell the user to preconnect even if they already are?
Seems like we have to exclude any currently preconnected origins from our recommendations, right?
async afterPass(passContext) { | ||
const driver = passContext.driver; | ||
|
||
// TODO(phulce): merge this with the main resource header values too |
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.
it does seem weird to do it both ways.
instead we could stick to the DOM methods and just new URL(href, finalUrl)
for the normalized href.
Or just use the JS version and ditch the other.
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.
oh we're not doing it both ways it returns the JS way, it seems I never pushed up the removal of the dead code in case people screamed bloody murder about doing it in browser-executed js :)
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.
k. sg
Yes, but there's a common case where they have added it incorrectly so it's not being used (i.e. missing
This PR is 3, but sounds like you're a fan of 2? |
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.
This PR is 3, but sounds like you're a fan of 2?
Hmmm. I guess I'm asking why we say ericbidelman.com should preconnect to https://fonts.googleapis.com
.. He already has the preconnect reference (with crossorigin). And it basically looks like the preconnect works? Perhaps this line isn't being satisfied, but probably should be?
// filter out all resources where origins are already resolved
UsesRelPreconnectAudit.hasAlreadyConnectedToOrigin(record) ||
Also unfortunately our UI for warnings in opps is kinda ugly:
const Gatherer = require('./gatherer'); | ||
const getElementsInDocumentString = require('../../lib/page-functions').getElementsInDocumentString; | ||
|
||
class LinkElements extends Gatherer { |
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.
should rename the file as well.
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.
done
async afterPass(passContext) { | ||
const driver = passContext.driver; | ||
|
||
// TODO(phulce): merge this with the main resource header values too |
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.
k. sg
return driver.evaluateAsync(`(() => { | ||
${getElementsInDocumentString}; | ||
|
||
return getElementsInDocument('link').map(link => { |
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.
There's probably a difference between link elems in head vs body that will be important at some point, but for now we can ignore it.
@@ -7,6 +7,8 @@ | |||
|
|||
const Gatherer = require('../gatherer'); | |||
|
|||
// TODO(phulce): remove this in favor of LinkElements gatherer |
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.
canonical too fwiw
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.
this is tracked by your issue now so I'll just remove anyway :)
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.
canonical too fwiw
this is tracked by your issue now so I'll just remove anyway :)
we should split those bullet points up into the implementation steps
@@ -28,6 +29,8 @@ const UIStrings = { | |||
description: | |||
'Consider adding preconnect or dns-prefetch resource hints to establish early ' + | |||
`connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).`, | |||
/** A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute on the link is a common mistake when adding preconnect links. */ | |||
crossoriginWarning: 'A preconnect link was found for "{securityOrigin}" but was not used.', |
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.
Let's mention crossorigin here in the warning.
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 feel weird calling these links. A preconnect "reference"?
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.
@wardpeet and I discussed and he suggested removing the mention of crossorigin, I somewhat agree and given our other positions it makes some sense to keep it in the docs
Now your warning message isn't super helpful. If I read it I would add crossorigin to the preconnect tag and I'll see the same message pop up. Sometimes crossorigin helps but the urls listed in the bugs do not get fixed by slapping crossorigin on it.
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.
- would it be terrible to do
"A preconnect <link> was..."
to make it clear what's being referenced? - if not going to mention crossorigin, does the string var need a new name?
"was not used"
is kind of ambiguous."was not used by the browser"
?"was not able to be used by the browser"
? followed? honored?- Is there any more hint we can give about what went wrong?
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.
would it be terrible
nope sounds good
if not going to mention crossorigin, does the string var need a new name?
heh, yes, but hang on one sec
is kind of ambiguous
was not used by the browser
SGTM
Is there any more hint we can give about what went wrong?
This is 99% a crossorigin
problem IMO, since you and Paul both are on that side and that was my first instinct as well, I think it's worth going back :) sorry @wardpeet!
but he doesn't? :) he's preconnecting to |
@@ -30,7 +30,7 @@ describe('Default Config', () => { | |||
|
|||
// And that they have the correct shape. | |||
opportunityResults.forEach(auditResult => { | |||
assert.strictEqual(auditResult.details.type, 'opportunity'); |
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.
any reason for this change?
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.
yeah I failed this test while I was working and the error message you get is useless, this way it shows you what audit details you actually did get back so you know where to go fix
@@ -28,6 +29,8 @@ const UIStrings = { | |||
description: | |||
'Consider adding preconnect or dns-prefetch resource hints to establish early ' + | |||
`connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).`, | |||
/** A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute on the link is a common mistake when adding preconnect links. */ | |||
crossoriginWarning: 'A preconnect link was found for "{securityOrigin}" but was not used.', |
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.
- would it be terrible to do
"A preconnect <link> was..."
to make it clear what's being referenced? - if not going to mention crossorigin, does the string var need a new name?
"was not used"
is kind of ambiguous."was not used by the browser"
?"was not able to be used by the browser"
? followed? honored?- Is there any more hint we can give about what went wrong?
const settings = context.settings; | ||
const preconnectLinks = artifacts.LinkElements.filter(el => el.rel === 'preconnect'); | ||
const preconnectOrigins = new Set(preconnectLinks.map(link => URL.getOrigin(link.href || ''))); |
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.
move these two lines down below where they're used?
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.
sure, done
*/ | ||
'use strict'; | ||
|
||
const Gatherer = require('./gatherer'); |
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 think we settled(ish) on .js
going forward?
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.
done
crossorigin: link.crossorigin, | ||
}; | ||
}); | ||
})()`, {useIsolation: true}); |
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 rare useIsolation
sighting!
rel: link.rel, | ||
href: link.href, | ||
as: link.as, | ||
crossorigin: link.crossorigin, |
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.
link.crossOrigin
(we probably want to go with the same camel case for the artifact property as well?)
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.
good points, maybe I shouldn't bring in attributes I'm not using yet 😆
types/artifacts.d.ts
Outdated
rel?: string | ||
href?: string | ||
as?: string | ||
crossorigin?: string |
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.
shouldn't these all be required since the browser will normalize to at least an empty string? Or we could have the gatherer explicitly drop ''
in favor of undefined
.
And from the spec/a quick test, crossorigin
can be null | 'anonymous' | 'use-credentials'
(the browser corrects anything else to `'anonymous')
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.
yeah, SGTM I'll change to match spec
@@ -1063,6 +1063,9 @@ Object { | |||
Object { | |||
"path": "accessibility", | |||
}, | |||
Object { | |||
"path": "external-resource-links", |
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.
travis failure is just needing to update this snapshot
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.
done
@@ -7,6 +7,8 @@ | |||
|
|||
const Gatherer = require('../gatherer'); | |||
|
|||
// TODO(phulce): remove this in favor of LinkElements gatherer |
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.
canonical too fwiw
this is tracked by your issue now so I'll just remove anyway :)
we should split those bullet points up into the implementation steps
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.
This seems great and love the new artifact.
Smoke testing for the gatherer will follow when the other audits are moved to use this artifact, but any chance of getting a preconnect warning smoke test as well? We have one suggested preconnect origin in preload_style.css
already, maybe we could add another and a failing <link rel="preconnect">
in the preload.html
test page?
this one is trickier because it needs new origins, are you onboard for introducing external internet dependencies into the local smoke tests? I was holding off because of that, but I think a google fonts smoketest for this would the ideal test case since it's also what I imagine is the most common real-world scenario |
ha, maybe it is time to give up on that. We do have the two static_server ports so we can technically request from a different origin (used in e.g. An external dependency is also not as big a deal as it once was for e.g. testing on a plane since I guess the big thing would be how flakey it would end up being. Ideally google fonts will be pretty reliable? |
Yeah but that's the one we're already using for real so we already ran out of origins to use for warnings! 😆
Yeah I agree here, I'll take the plunge |
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!
over to @paulirish
types/artifacts.d.ts
Outdated
rel: string | ||
href: string | ||
as: string | ||
crossOrigin: string|null |
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.
not worth the extra specificity?
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.
not totally sure which direction you're suggesting going :)
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.
'anonymous'|'use-credentials'|null
instead of just string|null
. It might not buy us anything (maybe if we end up with a switch statement somewhere).
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.
oh gotcha, sure!
👏 sweet, looking good |
Summary
This PR adds a warning to the preconnect audit when the origin is found in a
link[rel=preconnect]
but still isn't being used. Usually it's because of a missingcrossorigin
but good to be aware of either way.I'd also like to start ignoring origins that were discovered within ~300 ms or so of the main document since that's basically what preconnect would do anyway, but thought I'd bring that up for discussion first.
#6676 also suggested mentioning a limit on the number of preconnect origins in our help text. I think that makes sense but goes against our "it's all in the learn more link" stance. Others Ok with it?
Related Issues/PRs
fixes #5932 #6676