I'm using Vue 3 and I try to implement a skeleton loader for a placeholder when the data is loading and I can see it works if I turn on throttling in the Network tab of the browser. However, when the data loads too quick, I can also see how the skeleton loader blinks.
Here I tried using a setTimeout and inside I put the isLoaded ref which value is set to true when the image is fully loaded. But what the delay does is it prolongs time, and I need to skeleton loader be not visible when the data loads fast. I want it only be visible, when the data loads slowly.
onMounted(() => {
const img = new Image(getSrc('.jpg'));
img.onload = () => {
setTimeout(() => {
isLoaded.value = true;
}, 300);
};
img.src = getSrc('.jpg');
});
Update:
This is how I use skeleton loader in the <template>:
<ItemCardSkeleton v-if="pending === false || !isLoaded" />
<template v-else>
<img
class="card__image"
:src="getSrc('.jpg')"
:alt="recipe.alt"
width="15.625rem"
loading="lazy" />
<div class="card__content">
<h2 class="card__title">{{ recipe.title }}</h2>
</div>
</template>
Please, give a solution.
I would leave the skeleton logic alone, just fade it in after some time, avoiding the jump in content if you delay displaying the skeleton (as discussed in @Phil's answer)
The example below, there's no skeleton visible for 1000ms, then the skeleton will fade in for 1000ms - the times are probably longer than you want, I just wrote it this way to see it actually working - so, just adjust the
animation-duration(andanimation-timing-functionif you want) as appropriate to your needsNot sure how your skeleton is done, but here's a non-vue demo in action