Виртуализация списков представляет собой оптимизацию рендеринга больших наборов данных, которая значительно улучшает производительность интерфейса пользователя. В библиотеке Petite-Vue это реализуется через динамическую отрисовку только видимых элементов на экране, что минимизирует затраты на рендеринг скрытых элементов. В этой статье рассматривается, как реализовать виртуализацию списков с использованием библиотеки Petite-Vue.
Идея виртуализации заключается в том, чтобы не рендерить все элементы списка сразу, а только те, которые в данный момент видны пользователю. Например, если у вас есть список из 1000 элементов, но на экране помещается только 10, то только эти 10 элементов будут созданы и отрисованы, а остальные — скрыты. Когда пользователь прокручивает список, видимые элементы обновляются, а скрытые остаются незамеченными для рендеринга.
Когда список становится очень длинным, рендеринг всех его элементов может значительно замедлить работу приложения. Виртуализация помогает:
В Petite-Vue виртуализация решается с помощью тех же принципов, что и в других фреймворках, однако с учётом лёгкости и минимализма самой библиотеки.
Для начала определим основной контейнер для списка. Обычно он представляет собой блок с фиксированной высотой, в котором будут отображаться элементы.
<div x-data="virtualList()" style="height: 400px; overflow-y: auto;">
<div :style="listStyle" x-ref="list" @scroll="onScroll">
<template x-for="item in visibleItems" :key="item.id">
<div :style="itemStyle(item)">
<p x-text="item.name"></p>
</div>
</template>
</div>
</div>
В этом примере создаём контейнер с прокручиваемым списком. Для его работы необходимо настроить:
x-data="virtualList()" — объявляем данные и методы для
виртуализации.x-ref="list" — ссылку на элемент списка для
отслеживания прокрутки.@scroll="onScroll" — обработчик события прокрутки,
который будет изменять отображаемые элементы.Чтобы управлять виртуализацией, нужно вычислить, какие элементы находятся в пределах видимой области. Для этого понадобится вычислять текущую позицию прокрутки и в зависимости от неё обновлять список видимых элементов.
function virtualList() {
return {
items: Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` })),
itemHeight: 40, // высота одного элемента
visibleCount: 10, // количество видимых элементов
buffer: 5, // количество элементов, которые должны быть выше и ниже видимой области
offsetTop: 0, // текущая позиция прокрутки
get listHeight() {
return this.items.length * this.itemHeight;
},
get visibleItems() {
const start = Math.max(0, Math.floor(this.offsetTop / this.itemHeight) - this.buffer);
const end = Math.min(this.items.length, Math.ceil((this.offsetTop + this.containerHeight) / this.itemHeight) + this.buffer);
return this.items.slice(start, end);
},
listStyle() {
return `height: ${this.listHeight}px;`;
},
itemStyle(item) {
const index = this.items.indexOf(item);
const top = index * this.itemHeight;
return `position: absolute; top: ${top}px; left: 0; width: 100%;`;
},
onScroll(event) {
this.offsetTop = event.target.scrollTop;
},
get containerHeight() {
return this.$refs.list.offsetHeight;
}
};
}
Здесь:
items — массив всех элементов списка.itemHeight — высота одного элемента, которая
используется для вычислений.visibleCount — количество элементов, которые
одновременно видны.buffer — буферизирующее количество элементов, которые
отрисовываются до и после видимой области, чтобы избежать мерцания.offsetTop — текущее значение прокрутки.Метод visibleItems отвечает за вычисление индекса
первого и последнего видимого элемента, исходя из текущей позиции
прокрутки. Эти элементы будут отображаться в контейнере.
Метод itemStyle определяет абсолютное позиционирование
каждого элемента на основе его индекса, что позволяет создавать эффект
виртуализации, где элементы “всплывают” в зависимости от прокрутки.
Для того чтобы список обновлялся по мере прокрутки, используется
метод onScroll, который отслеживает изменение позиции
прокрутки и обновляет offsetTop, что в свою очередь влияет
на отображаемые элементы. Это позволяет динамически изменять видимый
список, не создавая всех элементов на странице.
Для улучшения производительности важно минимизировать количество
вычислений и изменений в DOM. В Petite-Vue это можно сделать, используя
директиву x-for, которая эффективно управляет изменениями в
списке. Кроме того, важно учитывать следующее:
Виртуализация списка в Petite-Vue позволяет:
Вместо того чтобы рисовать и обновлять все элементы списка, виртуализация в Petite-Vue позволяет работать только с теми, которые реально видны на экране, значительно улучшая пользовательский опыт при прокрутке больших списков.