Сделайте прокрутку более эффективной с помощью виртуального списка прокрутки, который увеличивает скорость загрузки страницы и предотвращает заикание веб-приложения.

Отображение элементов в DOM по отдельности может привести к значительному снижению производительности для пользователей, особенно при прокрутке больших списков. Чтобы сделать прокрутку более эффективной, мы должны использовать виртуальный список прокрутки, который увеличивает скорость загрузки страницы и предотвращает заикание веб-приложения.

Виртуальный список прокрутки аналогичен стандартному списку прокрутки, однако в любой момент отображаются только данные в текущем представлении пользователя. Когда пользователь прокручивает страницу вниз, новые элементы отображаются, а старые удаляются.

В этой статье мы рассмотрим vue-virtual-scroll-list, замечательную библиотеку для создания виртуальных списков прокрутки в Vue.js. Давайте начнем!

Рендеринг контента в vue-virtual-scroll-list

Библиотека vue-virtual-scroll-list имеет два основных метода для преобразования содержимого веб-страницы в список: режим item и режим v-for.

Режим item идеально подходит для рендеринга статического контента. Как только содержимое добавляется в DOM, режим item освобождает используемую память. Если вы измените данные, вам нужно будет вызвать forceRender() и запустить процесс заново.

Для рендеринга динамического контента лучше выбрать режим v-for. В режиме v-for на данные, представленные в списке, ссылаются внутри памяти. Поэтому при изменении данных элементы списка перерисовываются, а контекст сохраняется.

Давайте подробнее рассмотрим библиотеку vue-virtual-scroll-list, сравнив производительность режима item с использованием виртуального списка прокрутки и без него.

Сначала мы создадим новый проект Vue.js и установим vue-virtual-scroll-list. Затем мы создадим список, используя случайно сгенерированные данные. Наконец, мы отобразим наш список с виртуальной прокруткой и без нее, сравнив производительность каждого из них.

Настройка проекта Vue.js

Во-первых, убедитесь, что на вашем компьютере установлен Vue.js. Создайте новый проект Vue.js с помощью следующей команды:

vue create virtual-scroll-demo

После настройки проекта установите библиотеку vue-virtual-scroll-list:

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

Теперь наш проект имеет следующую структуру:

Создание списка

Теперь, когда у нас есть основа для нашего проекта, давайте начнем с основы для создания обоих наших списков.

Перейдите в папку /src и создайте файл с именем data.js. Давайте добавим следующую простую функцию, которая генерирует случайные данные в 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;
}

Далее мы создадим новый файл с именем Item.vue, который является компонентом item, который мы будем визуализировать. В Item.vue мы включим следующий блок кода, который создает шаблон и стиль для нашего списка, а также свойства, которые извлекают и отображают сгенерированные выше данные:

<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>

Отображение списка без виртуальной прокрутки

Теперь, когда у нас есть созданный список, давайте отобразим элементы списка в нашей модели DOM без использования vue-virtual-scroll-list. Добавьте следующий код в 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>

В приведенном выше блоке кода мы визуализировали 100 000 элементов в нашей модели DOM. Давайте посмотрим, как наш список будет работать с таким количеством данных и без виртуальной прокрутки. Запустите проект с помощью следующей команды npm:

npm run serve

Мы получим следующий вывод:

Когда мы проверим элемент inspect в браузере, мы увидим, что все элементы HTML были добавлены к DOM браузера, как показано на изображении ниже:

Добавление элементов в DOM браузера увеличит размер DOM. Поэтому браузеру потребуется больше времени для добавления каждого элемента в DOM, что может привести к значительному снижению производительности. Давайте внимательно посмотрим, сколько времени потребовалось браузеру, чтобы добавить наш список в DOM:

Событие DOMContentLoaded запускается через 22 секунды, что означает, что вкладка браузера загружается в течение 22 секунд, прежде чем отобразится окончательный отрендеренный список. Точно так же, как видно на изображении ниже, рендеринг нашего списка потреблял 128 МБ памяти:

Рендеринг списка с виртуальной прокруткой

Теперь давайте попробуем отобразить наш список с помощью виртуальной прокрутки. Импортируйте пакет vue-virtual-scroll-list в 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");

Далее мы визуализируем данные для элементов внутри компонента virtual-list. Давайте изменим наш файл App.js, чтобы он выглядел как следующий блок кода:

<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>

Обратите внимание, что реквизиты данных необходимы для виртуального списка для отображения элементов. Выполнение приведенного выше блока кода даст нам следующий результат:

На изображении ниже мы видим, что одновременно визуализируются только несколько элементов. Когда пользователь прокручивает вниз, отображаются новые элементы:

Теперь наше DOM-дерево намного меньше, чем раньше! Когда мы визуализируем наш виртуальный список прокрутки, DOMContentLoaded будет срабатывать намного быстрее, чем раньше!

Как видно на изображении выше, событие сработало всего за 563 миллисекунды. Точно так же наша операция потребляла всего 79 МБ памяти, что намного меньше, чем когда мы не использовали виртуальную прокрутку.

Заключение

Теперь вы знаете, как создать виртуальный список прокрутки в Vue.js с помощью библиотеки vue-virtual-scroll-list!

В этом руководстве мы создали статический список, в котором используются случайно сгенерированные данные, а затем реализовали его в нашем приложении Vue.js, сравнив его производительность с использованием виртуальной прокрутки и без нее.

Виртуальные списки прокрутки очень эффективны, особенно когда у вас большой список элементов на вашей веб-странице. Использование виртуального списка прокрутки может увеличить скорость загрузки страницы и улучшить взаимодействие с пользователем в целом.

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord . Заинтересованы в хакинге роста? Ознакомьтесь с разделом Схема.