framework
framework copied to clipboard
feat(nuxt3): support `prefetch` prop for `<nuxt-link>`
🔗 Linked issue
#3649 #2086
❓ Type of change
- [ ] 📖 Documentation (updates to the documentation or readme)
- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
- [ ] 👌 Enhancement (improving an existing functionality like performance)
- [x] ✨ New feature (a non-breaking change that adds functionality)
- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)
📚 Description
Support prefetch prop for <nuxt-link>. This implementation is refer to https://github.com/nuxt/framework/discussions/2086#discussioncomment-1683819. Need a polyfill for requestIdleCallback ?
Also, I'm not sure how to use Link Prefetching like below, because path are unpredictable.
<link rel="prefetch" as="script" href="path" />
The implementation of this PR refers to nuxt2, maybe we can generate a router manifest. and mapping file path when triggering prefetch ?
📝 Checklist
- [x] I have linked an issue or discussion.
- [x] I have updated the documentation accordingly.
Deploy Preview for nuxt3-docs canceled.
| Name | Link |
|---|---|
| Latest commit | b7bea156255da5ae017570e939f9fd5552ec1fc9 |
| Latest deploy log | https://app.netlify.com/sites/nuxt3-docs/deploys/6320e387fc714e0008189c59 |
Thank you for the PR @Mini-ghost 💚
From what I see, requestIdleCallback is not supported in Safari without a flag: https://caniuse.com/requestidlecallback
So I guess we need a polyfill for it, what would be the preferred approach to do so @pi0 ?
@pi0 @Atinux I will add polyfill for requestIdleCallback. And I think we have two way to polyfill.
- import polyfill at topest of the file and run in client side.
const requestIdleCallback = process.client
? window.requestIdleCallback || function (cb) {
const start = Date.now()
const idleDeadline = {
didTimeout: false,
timeRemaining () {
return Math.max(0, 50 - (Date.now() - start))
}
}
return window.setTimeout(function () {
cb(idleDeadline)
}, 1)
}
: (() => {}) as any as Window['requestIdleCallback']
- When component mounted and need prefetch, implement with Singleton.
let requestIdleCallback: Window['requestIdleCallback'] | null = null
onMounted(() => {
if (!shouldPrefetch.value) { return }
// add `requestIdleCallback` polyfill if not supported and need prefetch
if (!requestIdleCallback) {
requestIdleCallback = window.requestIdleCallback || function (cb) {
const start = Date.now()
const idleDeadline = {
didTimeout: false,
timeRemaining () {
return Math.max(0, 50 - (Date.now() - start))
}
}
return window.setTimeout(function () {
cb(idleDeadline)
}, 1)
}
}
})
Which is the preferred approach?
@Mini-ghost The first approach seems better to me 👍
Thank you so much for helping on this feature @Mini-ghost <3
I've made few more reactors to the PR to simplify do small fixes and also integrated with new payload prerendering using link:prefetch hook to be ready to land.