Performance: Loading states pattern
This pattern affects how quickly users see feedback during data fetching, impacting perceived load speed and interaction responsiveness.
<template> <div :aria-busy="loading" aria-live="polite"> <div v-if="loading" class="simple-loader" role="status" aria-label="Loading content"></div> <DataDisplay v-else :data="data" /> </div> </template> <script setup> import DataDisplay from './DataDisplay.vue' import { ref, onMounted } from 'vue' const loading = ref(true) const data = ref(null) async function fetchData() { // simulate data fetching return new Promise(resolve => setTimeout(() => resolve({}), 1000)) } onMounted(async () => { data.value = await fetchData() loading.value = false }) </script> <style scoped> .simple-loader { width: 2rem; height: 2rem; border: 0.25rem solid #ccc; border-top-color: #333; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } </style>
<template> <div v-if="loading"> <HeavySpinnerComponent /> </div> <div v-else> <DataDisplay :data="data" /> </div> </template> <script setup> import HeavySpinnerComponent from './HeavySpinnerComponent.vue' import DataDisplay from './DataDisplay.vue' import { ref, onMounted } from 'vue' const loading = ref(true) const data = ref(null) async function fetchData() { // simulate data fetching return new Promise(resolve => setTimeout(() => resolve({}), 1000)) } onMounted(async () => { data.value = await fetchData() loading.value = false }) </script>
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Heavy spinner component | High (many nodes) | Multiple reflows on toggle | High paint cost due to SVG and complex styles | [X] Bad |
| Simple CSS loader | Low (few nodes) | Single reflow | Low paint cost with simple animation | [OK] Good |
isLoading is true?v-if usagev-if conditionally renders the element only if the expression is true.isLoading is true, so v-if="isLoading" is correct.const isLoading = ref(true);
setTimeout(() => { isLoading.value = false; }, 2000);
What will the component show initially if template has <div v-if="isLoading">Loading...</div><div v-else>Content Loaded</div>?isLoadingtrue, so v-if="isLoading" shows "Loading..." initially.isLoading.value becomes false, switching to v-else content "Content Loaded".const isLoading = ref(false);
function fetchData() {
isLoading = true;
fetch('/api/data')
.then(() => { isLoading = false; });
}.value, not by direct assignment.isLoading = true instead of isLoading.value = true, causing errors.isLoading reactive variable?:disabled="isLoading" to disable the button when loading.isLoading.Pass the test and this pattern moves unknown