Files
inkreach-official-website/apps/website/.agents/skills/vue-best-practices/references/component-async.md
T
yeuimu 6c61a4e871 feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma
  binaryTargets for openssl 3.0
- nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal
  cron, http->https redirect
- prisma: add origin_goods.delisted migration, sync missing schema
  (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz
- api: CORS wildcard reflection, helmet CORP cross-origin, price
  backfill in persistProductDetail, categoryIcon ancestor fallback,
  mediaByColor per-color gallery in public goods detail
- admin: /admin base path (vite + router)
- import-data.mjs: udt_name casting, serial sequence advance fix
2026-08-26 14:23:09 +08:00

2.6 KiB

title, impact, impactDescription, type, tags
title impact impactDescription type tags
Async Component Best Practices MEDIUM Poor async component strategy can delay interactivity in SSR apps and create loading UI flicker best-practice
vue3
async-components
ssr
hydration
performance
ux

Async Component Best Practices

Impact: MEDIUM - Async components should reduce JavaScript cost without degrading perceived performance. Focus on hydration timing in SSR and stable loading UX.

Task List

  • Use lazy hydration strategies for non-critical SSR component trees
  • Import only the hydration helpers you actually use
  • Keep loadingComponent delay near the default 200ms unless real UX data suggests otherwise
  • Configure delay and timeout together for predictable loading behavior

Use Lazy Hydration Strategies in SSR

In Vue 3.5+, async components can delay hydration until idle time, visibility, media query match, or user interaction.

BAD:

<script setup lang="ts">
import { defineAsyncComponent } from 'vue'

const AsyncComments = defineAsyncComponent({
  loader: () => import('./Comments.vue')
})
</script>

GOOD:

<script setup lang="ts">
import {
  defineAsyncComponent,
  hydrateOnVisible,
  hydrateOnIdle
} from 'vue'

const AsyncComments = defineAsyncComponent({
  loader: () => import('./Comments.vue'),
  hydrate: hydrateOnVisible({ rootMargin: '100px' })
})

const AsyncFooter = defineAsyncComponent({
  loader: () => import('./Footer.vue'),
  hydrate: hydrateOnIdle(5000)
})
</script>

Prevent Loading Spinner Flicker

Avoid showing loading UI immediately for components that usually resolve quickly.

BAD:

<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import LoadingSpinner from './LoadingSpinner.vue'

const AsyncDashboard = defineAsyncComponent({
  loader: () => import('./Dashboard.vue'),
  loadingComponent: LoadingSpinner,
  delay: 0
})
</script>

GOOD:

<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import LoadingSpinner from './LoadingSpinner.vue'
import ErrorDisplay from './ErrorDisplay.vue'

const AsyncDashboard = defineAsyncComponent({
  loader: () => import('./Dashboard.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorDisplay,
  delay: 200,
  timeout: 30000
})
</script>

Delay Guidelines

Scenario Recommended Delay
Small component, fast network 200ms
Known heavy component 100ms
Background or non-critical UI 300-500ms