Skip to content
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

Use <link rel=“prefetch”> for prefetching #5737

Merged
merged 5 commits into from
Nov 24, 2018

Conversation

timneutkens
Copy link
Member

@timneutkens timneutkens commented Nov 23, 2018

Fixes #5734

Note that this makes prefetch no longer return the page object, as we're only injecting prefetch tags

@timneutkens timneutkens changed the title Use <link rel=“prefetch”> for prefetching [WIP] Use <link rel=“prefetch”> for prefetching Nov 23, 2018
@timneutkens timneutkens changed the title [WIP] Use <link rel=“prefetch”> for prefetching Use <link rel=“prefetch”> for prefetching Nov 23, 2018
@timneutkens timneutkens merged commit cad19c8 into vercel:canary Nov 24, 2018
@timneutkens timneutkens deleted the fix/optimize-prefetch branch November 25, 2018 00:13
// Mainly this is for Safari
// https://caniuse.com/#feat=link-rel-prefetch
// https://caniuse.com/#feat=link-rel-preload
link.rel = supportsPrefetch ? 'prefetch' : 'preload'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't semantically the same. Prefetch should only be used for future navigations (as in full page loads). For sub-resources fetches (like this one), preload is the right one to use.

Prefetch may appear to work for client side navigations, but may lead to double-downloads if the prefetch hasn't finished by the time the actual request is made. That is because preload hits the memory cache (which de-dupes requests) while prefetch is only de-duped once the response made it into the disk cache.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm interesting, so you're saying we should use preload instead, but that triggers a warning if not used within 3 seconds, which is likely to cause confusion to users of Next.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there really needs to be a "I know what I'm doing" flag to remove that warning. Very similar things happen with lazy loading resources before rendering where render-time depends on scroll.

CC @yoavweiss @igrigorik for actually authoritative advice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created this PR: #5744

Will merge it once @yoavweiss / @igrigorik get back about this.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed preload is a better choice for same page resources. On top of that, the future of prefetch for subresources is a bit murky.

// https://caniuse.com/#feat=link-rel-preload
link.rel = supportsPrefetch ? 'prefetch' : 'preload'
link.href = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
link.as = 'script'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding the importance attribute to lower priority.
https://www.chromestatus.com/feature/5273474901737472

Unfortunately when this is fixed to use preload it will use the default priority for script.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should be using importance before it actually ships, as that can lock us out of that API shape if we'd want to change the API in some way. You're right that in terms of priority here, it'd use the default priority which is not ideal, but adding an importance attribute won't change it until it ships. I suggest we'll add it once it does.

clearCache (route) {
route = this.normalizeRoute(route)
delete this.pageCache[route]
delete this.loadingRoutes[route]
delete this.loadingRoutes[route]
Copy link
Contributor

@joecohens joecohens Nov 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timneutkens this one looks duplicated, were you trying to delete from prefetchCache?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I saw that while adding Malte's feedback, will be in my upcoming PR.

timneutkens added a commit that referenced this pull request Nov 26, 2018
…5744)

Based on #5737 (comment)

This will cause a warning in chrome/safari after 3s
@lock lock bot locked as resolved and limited conversation to collaborators Nov 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Defer prefetching after onload
5 participants