I have encountered problem that I am not capable of solving. I have high total blocking time on my page (2 sec). I have tried loading every vue component asynchronously, but it does not matter, still 2 sec tbt. I don't really understand what can cause such high tbt and what can I do about it, as it is just a simple page without much underlying logic (https://i.stack.imgur.com/o7LSk.png) (Just 21 simple cards).
I have removed everything I can, compressed code, and left only the most nessesary stuff. Still it does not solve the issue. Is there any way to make it go down to 100-200ms? What can cause such a problem in your experience?
I have high amount of components though (cards, buttons, lazy-load picture, rating), so in the end there will be around 100-300 components on page. But I don't see there any possibilities of removing it, as this will break neat structure
CodePudding user response:
The only way I found to fix high total blocking time in this case, is to use intersection observer and load it only when it enters the screen. I think same job can do some virtual scroller plugin.
<template>
<div class="grid">
<div class="grid__item" v-for="item in items" :data-id="item.id">
<Item v-if="itemsInScreen[item.id]" :item="item" />
</div>
</div>
</template>
<script>
export default {
name: 'Grid',
props: {
items: {required: true}
},
data() {
return {
itemsInScreen: {}
}
},
methods: {
initObserver() {
const callback = entries => {
entries.forEach(entry => {
if(entry.isIntersecting) this.$set(this.itemsInScreen, entry.target.dataset.id, true);
});
};
const options = {
rootMargin: "20px 20px 20px 20px"
};
const observer = new IntersectionObserver(callback, options);
const itemEls = this.$el.querySelectorAll('.grid__item');
itemEls.forEach(itemEl => observer.observe(itemEl));
}
},
mounted() {
this.initObserver();
}
}
</script>