I'm making an e-commerce type menu in Vue.js, with items which are divs that contain a fair amount of functionality and images. Performance is fairly good when rendering about 200 of these items, but when more than that many are added the site begins to perform sluggishly.
What's the best way to conditionally hide or remove Vue elements from the DOM if they are outside the current scrollable view (like ScrollViews in iOS)? Are there any plugins or libraries that can help with the performance of long lists of data items in Vue.js?
Thanks!
I've made a demo snippet using the package I mentioned in my comment.
I've made a "signal" item that acts as the watcher. When the "signal" item leaves the viewport, the "complex-stuff" is no longer rendered. I did it this way so you can see the "complex-stuff" disappear. When the "signal" scrolls back into view, the "complex-stuff" is rendered.
You could just put the watcher on the widget root element and things will only be hidden when the whole widget is out of view. You don't want to put the v-if
on the root element, though, or it will never come back once it goes away.
const containerMonitor = scrollMonitor.createContainer(document.body);
new Vue({
el: '#app',
data: {
ids: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
},
components: {
widget: {
template: '#widget-template',
props: ['id'],
data() {
return {
visible: true
};
},
mounted() {
const elementWatcher = containerMonitor.create(this.$el.querySelector('.signal'));
elementWatcher.enterViewport(() => {
this.visible = true;
});
elementWatcher.exitViewport(() => {
this.visible = false;
});
}
}
}
});
.widget-container {
height: 200px;
margin: 10px;
background-color: #f0f0f0;
display: flex;
flex-flow: row wrap;
}
.signal {
height: 10px;
width: 10px;
margin: 30px;
background-color: red;
border: thin solid blue;
}
.complex-stuff {
flex-basis: 100%;
padding: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<script src="https://rawgit.com/stutrek/scrollMonitor/master/scrollMonitor.js"></script>
<template id="widget-template">
<div class="widget-container">
<div class="signal">
</div>
<div v-if="visible" class="complex-stuff">
This is widget {{id}}.
Blah blah blah.
</div>
</div>
</template>
<div id="app">
Widgets below:
<widget v-for="id in ids" :id="id"></widget>
:widgets above
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With