Performance: Loading states pattern
MEDIUM IMPACT
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 |