Rendering items on the DOM alone can cause significant performance delays for users, especially when they scroll through large lists. To make scrolling more efficient, we should use virtual scroll lists, which can improve page loading speed and prevent web applications from stuttering.

A virtual scroll list is similar to a standard scroll list, however, only the data in the user’s current view is presented at any one time. As the user scrolls down the page, the new item is presented as the old item is deleted.

In this article, we will explore vue-virtual-scrolllist, an amazing library for creating virtual scrolllists in vue.js. Let’s get started!

Render content invue-virtual-scroll-list

The Vue-virtual-scroll list library has two main methods for rendering web content into a list, namely item mode and V-for mode.

The Item mode is ideal for rendering static content. Once the content is appended to the DOM, the Item mode frees the memory being used. If you change the data, you will need to call forceRender() and restart the process.

To render dynamic content, a better option is v-for mode. In V-for mode, the data supplied to the list is referenced in memory. Therefore, when the data changes, the list items are re-rendered and the context is maintained.

Let’s take a closer look at the vue-virtual-scrolllist library by comparing the performance of the Item mode with and without virtual scrolllist.

First, we’ll create a new vue.js project and install vue-virtual-scroll list. We will then create a list using randomly generated data. Finally, we’ll render our lists with and without virtual scrolling to compare their performance.

Set up a vue.js project

First, make sure you have vue.js installed on your machine. Create a new vue.js project with the following command.

vue create virtual-scroll-demo

Copy the code

Once the project is set up, install the vue-virtual-scroll list library.

npm install vue-virtual-scroll-list --save

Copy the code

Now, our project has the following structure.

Make a list

Now that we have established the foundation of the project, let’s start laying the groundwork for creating two lists.

Navigate to your/SRC folder and create a file called data.js. Let’s add the following simple function that generates random data to data.js.

let idCounter = 0;

export function getData(count) {
  const data = [];
  for (let index = 0; index < count; index++) {
    data.push({
      id: String(idCounter++),
      text: Math.random()
        .toString(16)
        .substr(10),
    });
  }
  return data;
}

Copy the code

Next, we will create a new file named item. vue, which is the Item component we will render. In item.vue, we will include the following code block that creates a template and style for our list, as well as props to retrieve and display the data generated above.

<template>
  <div class="item">
    <div class="id">{{ source.id }} - {{ source.text }}</div>
  </div>
</template>

<script>
export default {
  name: 'item',
  props: {
    source: {
      type: Object,
      default() {
        return {}
      }
    }
  }
}
</script>

<style scoped>
.item {
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid lightgrey;
  padding: 1em;
}
</style>

Copy the code

Render a list without virtual scrolling

Now that we’ve created a list, let’s render the list items on our DOM without using vue-virtual-scroll list. Add the following code to app.vue.

<template>
  <div id="app">
    <div class="wrapper">
    <div class="list">
      <p  v-for="item in items" :key="item">
    {{item}}
  </p>
      </div>

    </div>
  </div>
</template>

<script>
import Item from './Item'
import { getData } from './data'

export default {
  name: 'App',
  data() {
    return {
      item: Item,
      items: getData(100000)
    }
  }
}
</script>

<style>
#app {
  text-align: center;
  color: #2c3e50;
  margin-top: 1em;
  padding: 1em;
}
.list {
  border: 2px solid red;
  border-radius: 3px;
}
</style>

Copy the code

In the code block above, we rendered 100,000 items in the DOM. Let’s see how our list performs with this much data and no virtual scrolling. Start the project with the following NPM command.

npm run serve

Copy the code

We get the following output.

When we examine the inspect element in the browser, we see that all the HTML elements are appended to the browser DOM, as shown in the figure below.

Appending elements to the browser DOM increases the DOM size. As a result, the browser will take more time to append each item to the DOM, potentially causing a significant performance lag. Let’s take a closer look at how long it takes the browser to append our list to the DOM.

The event DOMContentLoaded launches after 22 seconds, meaning that the browser TAB takes 22 seconds to load before displaying the final rendered list. Similarly, as shown below, rendering our list consumed 128MB of memory.

Render a list with a virtual scroll

Now, let’s try rendering our list with a virtual scroll. Import the vue-virtual-scroll-list package in main.js.

import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;

import VirtualList from "vue-virtual-scroll-list";

Vue.component("virtual-list", VirtualList);
new Vue({
  render: (h) => h(App),
}).$mount("#app");

Copy the code

Next, we will render the data for the items within the Virtual-list component. Let’s change our app.js file to look like the following code block.

<template>
  <div id="app">
    <div class="wrapper">


       <virtual-list
        class="list"
        style="height: 360px; overflow-y: auto;"
        :data-key="'id'"
        :data-sources="items"
        :data-component="item"
        :estimate-size="50"
      />
    </div>
  </div>
</template>

<script>
import Item from './Item'
import { getData } from './data'

export default {
  name: 'App',
  data() {
    return {
      item: Item,
      items: getData(100000)
    }
  }
}
</script>

<style>
#app {
  text-align: center;
  color: #2c3e50;
  margin-top: 1em;
  padding: 1em;
}
.list {
  border: 2px solid red;
  border-radius: 3px;
}
</style>

Copy the code

Note that data items are required for virtual list rendering projects. Running the above code block will give us the following output.

As we can see in the image below, only a few items are rendered at a time. As the user scrolls down, more items are presented.

Now, our DOM tree is much smaller than it used to be, and DOMContentLoaded will be much faster when we render our virtual scrolling list!

As shown in the figure above, the event was triggered in 563 milliseconds. Again, our operation only consumed 79MB of memory, which is much less than if we hadn’t used virtual scrolling.

conclusion

Now you know how to create a virtual scrolllist in vue.js using the vue-virtual-scrolllist library.

In this tutorial, we created a static list using randomly generated data and then implemented it in our vue.js application, comparing performance with and without virtual scrolling.

Virtual scrolling lists perform well, especially if you have a large list of items on your web page. Using virtual scroll lists can speed up page loading and improve the overall user experience