Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.

Commit f3499d7

Browse files
danielroepi0
andauthored
feat(nuxt): allow programmatically prefetching global components (#6661)
Co-authored-by: Pooya Parsa <[email protected]>
1 parent 1bce4df commit f3499d7

File tree

8 files changed

+97
-2
lines changed

8 files changed

+97
-2
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# `prefetchComponents`
2+
3+
::StabilityEdge
4+
::
5+
6+
Nuxt provides composables and utilities to give you fine-grained control over prefetching and preloading components.
7+
8+
> Prefetching component downloads the code in the background, this is based on the assumption that the component will likely be used for rendering, enabling the component to load instantly if and when the user requests it. The component is downloaded and cached for anticipated future use without the user making an explicit request for it.
9+
10+
You can use `prefetchComponents` to manually prefetch individual components that have been registered globally in your Nuxt app. (By default Nuxt registers these as async components.) You must use the Pascal-cased version of the component name.
11+
12+
```js
13+
await prefetchComponents('MyGlobalComponent')
14+
15+
await prefetchComponents(['MyGlobalComponent1', 'MyGlobalComponent2'])
16+
```
17+
18+
::alert{icon=👉}
19+
Current implementation behaves exactly the same as [`preloadComponents`](/api/composables/preload-components) by preloading components instead of just prefetching we are working to improve this behavior.
20+
::
21+
22+
::alert{icon=👉}
23+
Currently, on server, `prefetchComponents` will have no effect.
24+
::
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# `preloadComponents`
2+
3+
::StabilityEdge
4+
::
5+
6+
Nuxt provides composables and utilities to give you fine-grained control over prefetching and preloading components.
7+
8+
> Preloading components loads components that your page will need very soon, which you want to start loading early in rendering lifecycle. This ensures they are available earlier and are less likely to block the page's render, improving performance.
9+
10+
You can use `preloadComponents` to manually preload individual components that have been registered globally in your Nuxt app. (By default Nuxt registers these as async components.) You must use the Pascal-cased version of the component name.
11+
12+
```js
13+
await preloadComponents('MyGlobalComponent')
14+
15+
await preloadComponents(['MyGlobalComponent1', 'MyGlobalComponent2'])
16+
```
17+
18+
::alert{icon=👉}
19+
Currently, on server, `preloadComponents` will have no effect.
20+
::

packages/nuxt/src/app/composables/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export type { CookieOptions, CookieRef } from './cookie'
1212
export { useRequestHeaders, useRequestEvent, setResponseStatus } from './ssr'
1313
export { abortNavigation, addRouteMiddleware, defineNuxtRouteMiddleware, navigateTo, useRoute, useActiveRoute, useRouter } from './router'
1414
export type { AddRouteMiddlewareOptions, RouteMiddleware } from './router'
15+
export { preloadComponents, prefetchComponents } from './preload'
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { Component } from 'vue'
2+
import { useNuxtApp } from '#app'
3+
4+
/**
5+
* Preload a component or components that have been globally registered.
6+
*
7+
* @param components Pascal-cased name or names of components to prefetch
8+
*/
9+
export const preloadComponents = async (components: string | string[]) => {
10+
if (process.server) { return }
11+
const nuxtApp = useNuxtApp()
12+
13+
components = Array.isArray(components) ? components : [components]
14+
await Promise.all(components.map(name => _loadAsyncComponent(nuxtApp.vueApp._context.components[name])))
15+
}
16+
17+
/**
18+
* Prefetch a component or components that have been globally registered.
19+
*
20+
* @param components Pascal-cased name or names of components to prefetch
21+
*/
22+
export const prefetchComponents = (components: string | string[]) => {
23+
// TODO
24+
return preloadComponents(components)
25+
}
26+
27+
// --- Internal ---
28+
29+
function _loadAsyncComponent (component: Component) {
30+
if ((component as any)?.__asyncLoader && !(component as any).__asyncResolved) {
31+
return (component as any).__asyncLoader()
32+
}
33+
}

packages/nuxt/src/components/templates.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface ComponentsTemplateContext {
1111
}
1212

1313
export type ImportMagicCommentsOptions = {
14-
chunkName:string
14+
chunkName: string
1515
prefetch?: boolean | number
1616
preload?: boolean | number
1717
}

packages/nuxt/src/imports/presets.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ const appPreset = defineUnimportPreset({
5151
'createError',
5252
'defineNuxtLink',
5353
'useAppConfig',
54-
'defineAppConfig'
54+
'defineAppConfig',
55+
'preloadComponents',
56+
'prefetchComponents'
5557
]
5658
})
5759

test/basic.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,12 @@ describe('automatically keyed composables', () => {
360360
})
361361
})
362362

363+
describe('prefetching', () => {
364+
it('should prefetch components', async () => {
365+
await expectNoClientErrors('/prefetch/components')
366+
})
367+
})
368+
363369
if (process.env.NUXT_TEST_DEV) {
364370
describe('detecting invalid root nodes', () => {
365371
it('should detect invalid root nodes in pages', async () => {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script setup lang="ts">
2+
await prefetchComponents('TestGlobal')
3+
</script>
4+
5+
<template>
6+
<div>
7+
Testing prefetching global components
8+
</div>
9+
</template>

0 commit comments

Comments
 (0)