N
Nuxt2mo ago
pearbender

slow drawer open

When I put a lot of content to render in my drawer it's slow to open. How can I make the drawer open fast but then render stuff
15 Replies
kapa.ai
kapa.ai2mo ago
Hi @pearbender. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- When you put a lot of content inside a Nuxt UI Drawer, the opening can feel slow because all the content is rendered immediately when the drawer opens. To improve perceived performance, you can delay the hydration (i.e., the interactive rendering) of heavy components inside the drawer until after the drawer is open. Nuxt supports several lazy (or delayed) hydration strategies for components. For example, you can use the hydrate-on-visible strategy to hydrate a component only when it becomes visible in the viewport, or hydrate-on-idle to hydrate when the browser is idle. This way, the drawer itself opens quickly, and the heavy content loads interactively afterward. Here’s how you might use lazy hydration for a component inside your drawer:
<template>
<UDrawer v-model:open="open">
<UButton label="Open" color="neutral" variant="subtle" />

<template #body>
<LazyHeavyComponent hydrate-on-visible />
</template>
</UDrawer>
</template>
<template>
<UDrawer v-model:open="open">
<UButton label="Open" color="neutral" variant="subtle" />

<template #body>
<LazyHeavyComponent hydrate-on-visible />
</template>
</UDrawer>
</template>
Replace LazyHeavyComponent with your actual component. You can also use other strategies like hydrate-on-idle, hydrate-on-interaction, or hydrate-after depending on your needs. This approach helps the drawer open instantly, while the heavy content loads in the background or after a user interaction. For more details on hydration strategies, see the Nuxt documentation on delayed or lazy hydration and the available options for when to hydrate components. This technique is especially useful for improving the user experience in content-heavy drawers or modals.<|vq_10913|> ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@779279431419559947> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
pearbender
pearbenderOP2mo ago
@kapa.ai Thanks! that fixed it. but my draw kind of "pops" now as its height changes once the rendered content becomes visible. how can i make the draw say 50% of vh always
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To make your Nuxt UI Drawer always take up 50% of the viewport height, you can use the snapPoints prop. This prop allows you to define the height of the drawer as a percentage of the screen. For example, to set the drawer to always be 50% of the viewport height, use:
<template>
<UDrawer :snap-points="[0.5]" :open="open">
<!-- Drawer content -->
</UDrawer>
</template>
<template>
<UDrawer :snap-points="[0.5]" :open="open">
<!-- Drawer content -->
</UDrawer>
</template>
This will ensure the drawer always opens to 50% of the viewport height, preventing the "pop" effect as content loads. You can also use pixel values if you want a fixed height instead. For more details, see the official documentation for the snapPoints prop in the Drawer component here<source>https://ui.nuxt.com/components/drawer#props</source.> ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@779279431419559947> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
pearbender
pearbenderOP2mo ago
@kapa.ai I think snap points is something different. i think we just need a tailwind class on an outer div
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct—if you want the drawer's content area to always be 50% of the viewport height, you can simply apply a Tailwind CSS class like h-[50vh] to a wrapper div inside the drawer. For example:
<template>
<UDrawer :open="open">
<template #body>
<div class="h-[50vh] overflow-auto">
<!-- Your heavy content here -->
</div>
</template>
</UDrawer>
</template>
<template>
<UDrawer :open="open">
<template #body>
<div class="h-[50vh] overflow-auto">
<!-- Your heavy content here -->
</div>
</template>
</UDrawer>
</template>
This ensures the content area always takes up 50% of the viewport height, regardless of when or how the content loads. You can also use other Tailwind height utilities as needed. The knowledge sources do not explicitly mention this approach, but they do show that you can customize the drawer's content area using classes and the ui prop for further customization if needed Drawer Theme<source>https://ui.nuxt.com/components/drawer#theme</source.> ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@779279431419559947> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
pearbender
pearbenderOP2mo ago
@kapa.ai cool it works. how can i render a skeleton while my lazy component renders
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You can use the USkeleton component from Nuxt UI to show a placeholder while your lazy component is loading. Wrap your lazy component in a conditional, and display the skeleton until the component is ready. Here’s an example pattern:
<template>
<UDrawer :open="open">
<template #body>
<div class="h-[50vh] overflow-auto">
<USkeleton v-if="!isLoaded" class="h-full w-full" />
<LazyHeavyComponent v-else @hook:mounted="isLoaded = true" />
</div>
</template>
</UDrawer>
</template>

<script setup>
import { ref } from 'vue'
const isLoaded = ref(false)
</script>
<template>
<UDrawer :open="open">
<template #body>
<div class="h-[50vh] overflow-auto">
<USkeleton v-if="!isLoaded" class="h-full w-full" />
<LazyHeavyComponent v-else @hook:mounted="isLoaded = true" />
</div>
</template>
</UDrawer>
</template>

<script setup>
import { ref } from 'vue'
const isLoaded = ref(false)
</script>
Alternatively, if you’re using defineAsyncComponent or dynamic imports, you can use the loading slot or a similar pattern to show USkeleton while the component is being loaded USkeleton Usage<source>https://ui.nuxt.com/components/skeleton</source.> For more on USkeleton, see the official documentation<source>https://ui.nuxt.com/components/skeleton</source.> ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@779279431419559947> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
pearbender
pearbenderOP2mo ago
@kapa.ai isLoaded never gets set to true. are you sure the mounted hook is what we want?
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct—using @hook:mounted on a component instance is not a standard or reliable way to detect when a lazy component has finished loading in Nuxt 3, and the knowledge sources do not mention this approach. A more idiomatic way in Nuxt is to use Vue's Suspense feature, which allows you to show a fallback (like a skeleton) while an async component is being resolved. However, the knowledge sources above do not provide a direct example of using Suspense with USkeleton and lazy components in Nuxt 3. What is documented is that you can use the USkeleton component as a placeholder while content is loading, but the exact integration with lazy components or Suspense is not detailed in the sources USkeleton Usage<source>https://ui.nuxt.com/components/skeleton</source.> If you need a robust solution, you may want to explore Vue's Suspense in your Nuxt app, but please note that the knowledge sources do not provide a step-by-step guide for this scenario. If you need more details, I recommend checking the official Vue documentation on Suspense or looking for Nuxt-specific examples as they become available. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@779279431419559947> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
pearbender
pearbenderOP2mo ago
Nuxt
components · Nuxt Directory Structure
The components/ directory is where you put all your Vue components.

Did you find this page helpful?