mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
fix(nuxt): defer render-blocking prefetches until after load (#9475)
This commit is contained in:
parent
c26979a047
commit
52421a9354
@ -193,23 +193,30 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
const shouldPrefetch = props.prefetch !== false && props.noPrefetch !== true && typeof to.value === 'string' && props.target !== '_blank' && !isSlowConnection()
|
const shouldPrefetch = props.prefetch !== false && props.noPrefetch !== true && typeof to.value === 'string' && props.target !== '_blank' && !isSlowConnection()
|
||||||
if (shouldPrefetch) {
|
if (shouldPrefetch) {
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
const observer = useObserver()
|
|
||||||
let idleId: number
|
let idleId: number
|
||||||
let unobserve: Function | null = null
|
let unobserve: Function | null = null
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
idleId = requestIdleCallback(() => {
|
const observer = useObserver()
|
||||||
if (el?.value?.tagName) {
|
function registerCallback () {
|
||||||
unobserve = observer!.observe(el.value, async () => {
|
idleId = requestIdleCallback(() => {
|
||||||
unobserve?.()
|
if (el?.value?.tagName) {
|
||||||
unobserve = null
|
unobserve = observer!.observe(el.value, async () => {
|
||||||
await Promise.all([
|
unobserve?.()
|
||||||
nuxtApp.hooks.callHook('link:prefetch', to.value as string).catch(() => {}),
|
unobserve = null
|
||||||
!isExternal.value && preloadRouteComponents(to.value as string, router).catch(() => {})
|
await Promise.all([
|
||||||
])
|
nuxtApp.hooks.callHook('link:prefetch', to.value as string).catch(() => {}),
|
||||||
prefetched.value = true
|
!isExternal.value && preloadRouteComponents(to.value as string, router).catch(() => {})
|
||||||
})
|
])
|
||||||
}
|
prefetched.value = true
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (nuxtApp.isHydrating) {
|
||||||
|
nuxtApp.hooks.hookOnce('app:suspense:resolve', registerCallback)
|
||||||
|
} else {
|
||||||
|
registerCallback()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (idleId) { cancelIdleCallback(idleId) }
|
if (idleId) { cancelIdleCallback(idleId) }
|
||||||
|
@ -142,6 +142,8 @@ export function createNuxtApp (options: CreateOptions) {
|
|||||||
|
|
||||||
if (hydratingCount === 0) {
|
if (hydratingCount === 0) {
|
||||||
nuxtApp.isHydrating = false
|
nuxtApp.isHydrating = false
|
||||||
|
// @ts-expect-error private flag
|
||||||
|
globalThis.__hydrated = true
|
||||||
return nuxtApp.callHook('app:suspense:resolve')
|
return nuxtApp.callHook('app:suspense:resolve')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,38 @@
|
|||||||
import { join, resolve } from 'pathe'
|
import { join, relative, resolve } from 'pathe'
|
||||||
import * as vite from 'vite'
|
import * as vite from 'vite'
|
||||||
import vuePlugin from '@vitejs/plugin-vue'
|
import vuePlugin from '@vitejs/plugin-vue'
|
||||||
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
|
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
|
||||||
import type { ServerOptions } from 'vite'
|
import type { ServerOptions } from 'vite'
|
||||||
import { logger } from '@nuxt/kit'
|
import { logger } from '@nuxt/kit'
|
||||||
import { getPort } from 'get-port-please'
|
import { getPort } from 'get-port-please'
|
||||||
import { joinURL, withoutLeadingSlash } from 'ufo'
|
import { joinURL, withoutLeadingSlash, withoutTrailingSlash } from 'ufo'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import type { OutputOptions } from 'rollup'
|
import type { OutputOptions } from 'rollup'
|
||||||
import { defineEventHandler } from 'h3'
|
import { defineEventHandler } from 'h3'
|
||||||
|
import { genString } from 'knitwork'
|
||||||
import { cacheDirPlugin } from './plugins/cache-dir'
|
import { cacheDirPlugin } from './plugins/cache-dir'
|
||||||
import type { ViteBuildContext, ViteOptions } from './vite'
|
import type { ViteBuildContext, ViteOptions } from './vite'
|
||||||
import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
|
import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
|
||||||
import { viteNodePlugin } from './vite-node'
|
import { viteNodePlugin } from './vite-node'
|
||||||
|
|
||||||
export async function buildClient (ctx: ViteBuildContext) {
|
export async function buildClient (ctx: ViteBuildContext) {
|
||||||
|
const buildAssetsDir = withoutLeadingSlash(
|
||||||
|
withoutTrailingSlash(ctx.nuxt.options.app.buildAssetsDir)
|
||||||
|
)
|
||||||
|
const relativeToBuildAssetsDir = (filename: string) => './' + relative(buildAssetsDir, filename)
|
||||||
const clientConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, {
|
const clientConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, {
|
||||||
entry: ctx.entry,
|
entry: ctx.entry,
|
||||||
base: ctx.nuxt.options.dev
|
base: ctx.nuxt.options.dev
|
||||||
? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, '/') || '/', ctx.nuxt.options.app.buildAssetsDir)
|
? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, '/') || '/', ctx.nuxt.options.app.buildAssetsDir)
|
||||||
: './',
|
: './',
|
||||||
experimental: {
|
experimental: {
|
||||||
renderBuiltUrl: (filename, { type, hostType }) => {
|
renderBuiltUrl: (filename, { type, hostType, hostId }) => {
|
||||||
|
// When rendering inline styles, we can skip loading CSS chunk that matches the current page
|
||||||
|
if (ctx.nuxt.options.experimental.inlineSSRStyles && hostType === 'js' && filename.endsWith('.css')) {
|
||||||
|
return {
|
||||||
|
runtime: `!globalThis.__hydrated ? ${genString(relativeToBuildAssetsDir(hostId))} : ${genString(relativeToBuildAssetsDir(filename))}`
|
||||||
|
}
|
||||||
|
}
|
||||||
if (hostType !== 'js' || type === 'asset') {
|
if (hostType !== 'js' || type === 'asset') {
|
||||||
// In CSS we only use relative paths until we craft a clever runtime CSS hack
|
// In CSS we only use relative paths until we craft a clever runtime CSS hack
|
||||||
return { relative: true }
|
return { relative: true }
|
||||||
|
Loading…
Reference in New Issue
Block a user