Чтобы большие списки быстрее реагировали на действия пользователя, реализуйте виртуальную прокрутку.
Прокручиваемый список – один из самых распространенных шаблонов интерфейса. Он используется и в лентах социальных сетей с бесконечной прокруткой, и в корпоративных панелях управления. Если списки прокрутки становятся очень длинными (сотни, тысячи или сотни тысяч элементов), производительность приложения может снизиться.
Большие списки могут загружаться медленно, поскольку приложению необходимо загрузить и отобразить все данные сразу. Они также могут медленно отображаться и перемещаться , поскольку каждый элемент в списке может содержать расширенные данные, мультимедиа и функциональные возможности.
Это может привести к проблемам при загрузке или прокрутке страницы, что вызовет у пользователей раздражение и заставит их покинуть сайт.
Виртуальная прокрутка в Angular с помощью Component Dev Kit
Виртуальная прокрутка – это основной метод, используемый для решения этих проблем масштабирования. Виртуальная прокрутка создает впечатление очень большого списка, предоставляя полосу прокрутки соответствующего размера и возможность навигации по списку без необходимости хранить весь список в памяти или отображать его на странице.
В Angular виртуальная прокрутка обеспечивается Component Dev Kit (CDK). Изменив способ итерации по спискам и предоставив пару дополнительных параметров конфигурации, виртуальная прокрутка CDK будет автоматически управлять виртуальным рендерингом ваших списков, повышая производительность и скорость отклика страницы.
Вместо того чтобы отображать весь список за раз, будет отображаться только подмножество элементов, которые помещаются на экране (плюс небольшой буфер). По мере навигации пользователя рассчитывается и отображается новый набор элементов, при необходимости повторно используя существующий DOM.
В оставшейся части этой статьи рассказывается, как настроить базовую виртуальную прокрутку. Полный рабочий пример можно посмотреть в этом примере приложения:
Настройка виртуальной прокрутки
Сначала убедитесь, что вы установили @angular/cdk с помощью менеджера пакетов. Чтобы установить его с помощью npm, выполните в терминале следующую команду:
npm install --save @angular/cdk
Добавьте ScrollingModule в свое приложение
После установки CDK импортируйте ScrollingModule, который обрабатывает виртуальную прокрутку, из пакета @angular/cdk/scrolling. Затем добавьте его в массив импорта вашего модуля:
import {ScrollingModule} from '@angular/cdk/scrolling';
...
imports: [
ScrollingModule
...
]
...
Как создать область просмотра
Чтобы посмотреть, как работает пакет,попробуйте создать компонент со списком чисел от 0 до 99 999:
@Component({
template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Когда браузер отрисовывает приложение, ему приходится отрисовывать 100 000 отдельных элементов <div>. Это может быть приемлемо для простых текстовых узлов, но любая сложность в повторяющемся шаблоне плохо масштабируется, а количество прослушивателей событий значительно увеличится.
Чтобы добавить виртуальную прокрутку и избежать этих проблем, необходимо создать область просмотра, обернув список в элемент <cdk-virtual-scroll-viewport>:
@Component({
template: `<cdk-virtual-scroll-viewport>
<div *ngFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Поскольку ScrollingModule динамически отображает подмножества списка, вам необходимо указать высоту области просмотра с помощью стандартного CSS. Также необходимо указать itemSize, чтобы сообщить области просмотра о ее контенте. Модуль использует эту информацию, чтобы определить, сколько элементов нужно хранить в DOM в определенный момент времени и как отобразить полосу прокрутки соответствующего размера.
@Component({
template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
<div *ngFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Наконец, преобразуйте *ngFor в *cdkVirtualFor:
@Component({
template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
<div *cdkVirtualFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Вместо того чтобы перебирать весь список, область просмотра динамически определяет и перебирает правильный поднабор списка для пользователя. Теперь, когда пользователь загружает страницу, CDK должен отобразить подмножество списка, которое помещается на экране (плюс небольшой буфер), а любые события прокрутки в области просмотра загружают и отображают соответствующее подмножество списка:
Дальнейшие действия
Возможности виртуальной прокрутки CDK выходят далеко за рамки этого базового примера. В примере приложения весь список находился в памяти, но в более сложных приложениях его можно получать по запросу. Подробнее о других возможностях ScrollingModule и директиве cdkVirtualOf можно узнать из раздела о Scrolling в документации по CDK.