mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
fix(nuxt): delay navigation until user input is acknowledged (#27743)
This commit is contained in:
parent
b026797d7b
commit
5e76587490
19
packages/nuxt/src/app/plugins/navigation-repaint.client.ts
Normal file
19
packages/nuxt/src/app/plugins/navigation-repaint.client.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { defineNuxtPlugin } from '../nuxt'
|
||||||
|
import { useRouter } from '../composables'
|
||||||
|
|
||||||
|
export default defineNuxtPlugin(() => {
|
||||||
|
useRouter().beforeResolve(async () => {
|
||||||
|
/**
|
||||||
|
* This gives an opportunity for the browser to repaint, acknowledging user interaction.
|
||||||
|
* It can reduce INP when navigating on prerendered routes.
|
||||||
|
*
|
||||||
|
* @see https://github.com/nuxt/nuxt/issues/26271#issuecomment-2178582037
|
||||||
|
* @see https://vercel.com/blog/demystifying-inp-new-tools-and-actionable-insights
|
||||||
|
*/
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
// Ensure we always resolve, even if the animation frame never fires
|
||||||
|
setTimeout(resolve, 100)
|
||||||
|
requestAnimationFrame(() => { setTimeout(resolve, 0) })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -532,6 +532,12 @@ async function initNuxt (nuxt: Nuxt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nuxt.options.experimental.navigationRepaint) {
|
||||||
|
addPlugin({
|
||||||
|
src: resolve(nuxt.options.appDir, 'plugins/navigation-repaint.client'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
nuxt.hooks.hook('builder:watch', (event, relativePath) => {
|
nuxt.hooks.hook('builder:watch', (event, relativePath) => {
|
||||||
const path = resolve(nuxt.options.srcDir, relativePath)
|
const path = resolve(nuxt.options.srcDir, relativePath)
|
||||||
// Local module patterns
|
// Local module patterns
|
||||||
|
@ -43,6 +43,10 @@ describe('resolveApp', () => {
|
|||||||
"mode": "client",
|
"mode": "client",
|
||||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/payload.client.ts",
|
"src": "<repoRoot>/packages/nuxt/src/app/plugins/payload.client.ts",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"mode": "client",
|
||||||
|
"src": "<repoRoot>/packages/nuxt/src/app/plugins/navigation-repaint.client.ts",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"mode": "client",
|
"mode": "client",
|
||||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/check-outdated-build.client.ts",
|
"src": "<repoRoot>/packages/nuxt/src/app/plugins/check-outdated-build.client.ts",
|
||||||
|
@ -417,5 +417,13 @@ export default defineUntypedSchema({
|
|||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
clientNodeCompat: false,
|
clientNodeCompat: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for a single animation frame before navigation, which gives an opportunity
|
||||||
|
* for the browser to repaint, acknowledging user interaction.
|
||||||
|
*
|
||||||
|
* It can reduce INP when navigating on prerendered routes.
|
||||||
|
*/
|
||||||
|
navigationRepaint: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user