Найти тему
Nuances of programming

3 способа визуализации больших списков в Angular

Оглавление

Источник: Nuances of Programming

1. Виртуальная прокрутка

Виртуальная прокрутка — наиболее эффективный способ обработки больших списков. Благодаря Angular CDK и другим плагинам ее можно с легкостью реализовать в любом компоненте.

Концепция проста:

  • элемент отображается только в том случае, если он находится в пределах видимых границ контейнера.

Чтобы использовать модуль прокрутки CDK, для начала нужно его установить:

npm i @angular/cdk

Затем импортируем модуль:

Теперь виртуальную прокрутку можно использовать в компонентах:

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

Если виртуальная прокрутка настолько хороша и проста в реализации, то зачем использовать другие методы? На это есть несколько причин:

  • Результат сильно зависит от реализации: трудно управлять всеми возможными сценариями с помощью одной единственной реализации. Чем сложнее элемент, тем сложнее предсказать результат.
  • Модуль — это еще один большой кусок кода, добавленный в приложение.
  • Доступность и практичность: скрытые элементы не отображаются и, следовательно, не доступны для поиска.

Виртуальная прокрутка — отличный вариант (если она работает) при наличии:

  • неопределенного и, возможно, огромного списка элементов (предположительно больше 5 Кб, однако зависит от сложности каждого элемента);
  • бесконечной прокрутки элементов.

2. Ручной рендеринг

Один из вариантов ускорения рендеринга большого списка элементов — это ручной рендеринг с использованием API Angular, вместо *ngFor.

Возьмем простой шаблон цикла ngFor:

Для расчета рендеринга 10000 простых элементов мы будем использовать бенчмарк, вдохновленный js-frameworks-benchmark.

Первый тест выполнен с помощью *ngFor. Результаты: на скриптинг потребовалось 1099 мс, на рендеринг — 1553 мс, а на покрас — 3 мс.

-2

С помощью API Angular эти элементы можно визуализировать вручную.

Код контроллера изменяется следующим образом:

  • объявляем шаблон и контейнер

@ViewChild('itemsContainer', { read: ViewContainerRef }) container: ViewContainerRef;
@ViewChild('item', { read: TemplateRef }) template: TemplateRef<any>;

  • после создания данных визуализируем их с помощью метода ViewContainerRef createEmbeddedViewwhen:

Результаты показывают небольшое улучшение:

  • Скриптинг — 734 мс, рендеринг — 1443 мс и покрас — 2 мс:
-3

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

Процесс выглядит следующим образом (движения мышь имитируют индикатор загрузки 😅):

-4

Теперь перейдем к прогрессивному рендерингу в сочетании с ручным.

3. Прогрессивный рендеринг

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

Код очень простой:

  • мы создаем интервал каждые 10 мс и отображаем 500 элементов одновременно;
  • когда все элементы будут отображены согласно индексу, мы останавливаем интервал и прерываем цикл.

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

Как видите, статистика выглядит хуже:

-5

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

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

Процесс выглядит следующим образом:

-6

Заключение

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

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

Читайте также:

Читайте нас в телеграмме и vk

Перевод статьи Giancarlo Buomprisco: 3 Ways to Render Large Lists in Angular