In NOVA LAB heavy cargo modules aren't loaded immediately - the system loads them on demand, displaying status on screen. Vue offers async components - loading components lazily (on demand) and Suspense - control over the loading state.
Instead of importing a component directly, you can load it asynchronously:
1<script setup>
2import { defineAsyncComponent } from 'vue'
3
4// Simple lazy import
5const HeavyModule = defineAsyncComponent(
6 () => import('./HeavyModule.vue')
7)
8</script>
9
10<template>
11 <HeavyModule />
12</template>The component is fetched only when it's needed (rendered in the template).
1<script setup>
2import { defineAsyncComponent } from 'vue'
3import LoadingSpinner from './LoadingSpinner.vue'
4import ErrorDisplay from './ErrorDisplay.vue'
5
6const HeavyModule = defineAsyncComponent({
7 // Loader function
8 loader: () => import('./HeavyModule.vue'),
9
10 // Component displayed during loading
11 loadingComponent: LoadingSpinner,
12
13 // Delay before showing loading component (ms)
14 delay: 200,
15
16 // Component displayed when loading fails
17 errorComponent: ErrorDisplay,
18
19 // Timeout - after this time the error component is shown (ms)
20 timeout: 10000
21})
22</script><Suspense> is a built-in Vue component for managing the loading state of asynchronous components:1<template>
2 <Suspense>
3 <!-- Main content (loaded component) -->
4 <template #default>
5 <HeavyModule />
6 </template>
7
8 <!-- Loading state -->
9 <template #fallback>
10 <div class="loading">
11 <p>Loading module...</p>
12 <div class="spinner"></div>
13 </div>
14 </template>
15 </Suspense>
16</template>Suspense emits events informing about the loading state:
1<template>
2 <Suspense
3 @pending="onPending"
4 @resolve="onResolve"
5 @fallback="onFallback"
6 >
7 <template #default>
8 <AsyncModule />
9 </template>
10 <template #fallback>
11 <LoadingSpinner />
12 </template>
13 </Suspense>
14</template>
15
16<script setup>
17const onPending = () => console.log('Loading started...')
18const onResolve = () => console.log('Loading complete!')
19const onFallback = () => console.log('Fallback displayed')
20</script>A component with
async setup or top-level await automatically becomes an async dependency for Suspense:1<!-- AsyncModule.vue -->
2<script setup>
3const data = await fetch('/api/module-data')
4 .then(r => r.json())
5</script>
6
7<template>
8 <div>{{ data.name }}</div>
9</template>