Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Enforces Vue 3 Composition API best practices with script setup, TypeScript, Pinia, and Vite.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/component-async.md
1---2title: Async Component Best Practices3impact: MEDIUM4impactDescription: Poor async component strategy can delay interactivity in SSR apps and create loading UI flicker5type: best-practice6tags: [vue3, async-components, ssr, hydration, performance, ux]7---89# Async Component Best Practices1011**Impact: MEDIUM** - Async components should reduce JavaScript cost without degrading perceived performance. Focus on hydration timing in SSR and stable loading UX.1213## Task List1415- Use lazy hydration strategies for non-critical SSR component trees16- Import only the hydration helpers you actually use17- Keep `loadingComponent` delay near the default `200ms` unless real UX data suggests otherwise18- Configure `delay` and `timeout` together for predictable loading behavior1920## Use Lazy Hydration Strategies in SSR2122In Vue 3.5+, async components can delay hydration until idle time, visibility, media query match, or user interaction.2324**BAD:**25```vue26<script setup lang="ts">27import { defineAsyncComponent } from 'vue'2829const AsyncComments = defineAsyncComponent({30loader: () => import('./Comments.vue')31})32</script>33```3435**GOOD:**36```vue37<script setup lang="ts">38import {39defineAsyncComponent,40hydrateOnVisible,41hydrateOnIdle42} from 'vue'4344const AsyncComments = defineAsyncComponent({45loader: () => import('./Comments.vue'),46hydrate: hydrateOnVisible({ rootMargin: '100px' })47})4849const AsyncFooter = defineAsyncComponent({50loader: () => import('./Footer.vue'),51hydrate: hydrateOnIdle(5000)52})53</script>54```5556## Prevent Loading Spinner Flicker5758Avoid showing loading UI immediately for components that usually resolve quickly.5960**BAD:**61```vue62<script setup lang="ts">63import { defineAsyncComponent } from 'vue'64import LoadingSpinner from './LoadingSpinner.vue'6566const AsyncDashboard = defineAsyncComponent({67loader: () => import('./Dashboard.vue'),68loadingComponent: LoadingSpinner,69delay: 070})71</script>72```7374**GOOD:**75```vue76<script setup lang="ts">77import { defineAsyncComponent } from 'vue'78import LoadingSpinner from './LoadingSpinner.vue'79import ErrorDisplay from './ErrorDisplay.vue'8081const AsyncDashboard = defineAsyncComponent({82loader: () => import('./Dashboard.vue'),83loadingComponent: LoadingSpinner,84errorComponent: ErrorDisplay,85delay: 200,86timeout: 3000087})88</script>89```9091## Delay Guidelines9293| Scenario | Recommended Delay |94|----------|-------------------|95| Small component, fast network | `200ms` |96| Known heavy component | `100ms` |97| Background or non-critical UI | `300-500ms` |98