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

feat(nuxt3): support auto-loading lazy and custom-resolved components #3814

Merged
merged 1 commit into from
Mar 22, 2022

Conversation

danielroe
Copy link
Member

πŸ”— Linked issue

for example, nuxt/nuxt#13483 - though not marking as resolving it as we may also wish to globally register NuxtLink

❓ 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)
  • ✨ New feature (a non-breaking change that adds functionality)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This PR:

  • adds components and autoImports keys to nuxt.config documentation
  • supports auto-loading Lazy-prefixed components
  • adds type-hinting for Lazy-prefixed components
  • supports custom resolving components with resolveComponent (to allow users to do more elaborate dynamic components without needing to set global: true, which can have a negative performance effect). See Dynamically creating <NuxtLink> with <Component> no longer worksΒ nuxt#13483 for example.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@danielroe danielroe added bug Something isn't working enhancement New feature or request nuxt3 components ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf labels Mar 21, 2022
@danielroe danielroe requested a review from pi0 March 21, 2022 12:08
@danielroe danielroe self-assigned this Mar 21, 2022
@netlify
Copy link

netlify bot commented Mar 21, 2022

βœ… Deploy Preview for nuxt3-docs ready!

πŸ”¨ Explore the source changes: a8854e7

πŸ” Inspect the deploy log: https://app.netlify.com/sites/nuxt3-docs/deploys/62386aa3a0da830008bd46ce

😎 Browse the preview: https://deploy-preview-3814--nuxt3-docs.netlify.app

@danielroe danielroe changed the title feat(nuxt3): support lazy and custom-resolved components feat(nuxt3): support auto-loading lazy and custom-resolved components Mar 21, 2022
@pi0
Copy link
Member

pi0 commented Mar 21, 2022

Instead of re-intorducing lazy- prefixed components, I believe we could expose a new global utility like getAsyncComponent() that basically wraps resolveComponent but also hints loader to use lazy imported version. In the future, we can use it for smarter prefetch of async components.

@danielroe
Copy link
Member Author

@pi0 So instead of:

<template>
  <LazyTheFooter v-if="someCondition" />
</template>

we would do:

<template>
  <component is="LazyTheFooter" v-if="someCondition" />
</template>

<script setup>
  const LazyTheFooter = resolveAsyncComponent('TheFooter')
</script>

Initially I think this is more verbose without need. We can use the <LazyTheFooter> to extract the same info for smarter prefetch. Where necessary to do something more custom, this PR already makes it possible to do const LazyTheFooter = resolveComponent('LazyTheFooter'), with the same effect as the resolveAsyncComponent call above.

@pi0
Copy link
Member

pi0 commented Mar 21, 2022

There are mainly two use cases for lazy loading components:

    1. When we intentionally want a component to be lazy-loaded because of it's size, etc.
    1. When we cannot predict their usage to detect at built-time and have to lazy load them.

I assume your example is the first case. When a file name ends with .async (Please see nuxt/components#212 for some context.) we assign a flag to it and regardless of the loader and global usage they are async. No need for Lazy prefix usage and all smart prefetching already possible.

Second is I guess what you mentioned as:

supports custom resolving components with resolveComponent (to allow users to do more elaborate dynamic components without needing to set global: true, which can have a negative performance effect).

<template>
  <component :is="clickable ? MyButton : 'div'" />
</template>
<script setup>
const MyButton = resolveComponent('MyButton')
</script>

This could be:

<template>
  <component :is="clickable ? MyButton : 'div'" />
</template>
<script setup>
const MyButton = resolveAsyncComponent('MyButton')
</script>

@danielroe
Copy link
Member Author

This PR is not introducing new functionality - the usage with Lazy prefix is already documented here and implemented with global components:

export default function (nuxtApp) {
for (const name in components) {
nuxtApp.vueApp.component(name, components[name])
nuxtApp.vueApp.component('Lazy' + name, components[name])
}
}

While I think .async is a nice idea, it's not implemented yet in Nuxt 3. Moreover, sometimes lazy loading doesn't make sense for every instance of a component. For example, if you are toggling between one component and another with v-if you might want lazy components so both are not loaded if not needed. Yet in another component you might always wish to import it.

@pi0 pi0 merged commit 29078bb into main Mar 22, 2022
@pi0 pi0 deleted the fix/lazy-components branch March 22, 2022 17:04
@danielroe danielroe added the 3.x label Jan 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3.x bug Something isn't working components enhancement New feature or request nuxt3 ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants