Как стать автором
Обновить

Комментарии 10

Я использовал что-то типа прогрессивного рендеринга, только триггером был скроллинг. Плюс в том, что не нужно тратить ресурсы на элементы, которые возможно не будут смотреть. Минус — возможно, на некоторых устройствах, скроллинг будет на мгновения подмерзать перед выводом очередной порции данных. Из подводных камней: нужно отлавливать события изменения размеров экрана и проверять размеры контейнера списка, на лету корректировать количество элементов которые нужно вывести. Иначе можно наткнуться на ситуацию когда скроллинг пропал, а все элементы еще не выведены.
Тогда если фантазировать, то можно сделать гибрид по типу рендерим за кадром N элементов, а если пользователь начал скролить, то опять за кадром подгружаем N элементов. Всё равно могут быть проблемы при агрессивном скроллинге, но тоже как решение
Да проблемы особо нет. Скроллинг просто упрется и продолжится когда новая пачка отрисуется. Если такое поведение нормально.
если подгрузка будет занимать больше времени для плавного скрола, то это очень будет злить. Встречал такие решения. Для меня лучше уже будут пустые элементы с надписью Loading чем постоянно натыкаться на блокировку скрола :)
Не, данные уже как правило получены. Откладывать именно отрисовку.
Навскидку — а если скрестить *ngFor и прогрессивный рендеринг? Ведь без этого мы теряем привязку данных к состоянию элемента массива и следить за его обновлением при необходимости нужно самим.

Я примерно так и делал недавно. Воспользовался тем, что можно довольно дешево пере-рендеривать один и тот же элемент списка, если он представлен компонентом с OnPush.
Код выглядит примерно так


@Component({
  template: `<item *ngFor="let item of displayedItems$ | async" [item]="item"></item>`
})
class ListComponent {
  // делаем observable input,
  // позволит отменять незаконченный рендеринг при получении нового массива items
  private _items$ = new ReplaySubject<Item[]>(1);
  @Input set items(value: Item[]) { this._items$.next(value) }

  displayedItems$ = this._items$.pipe(switchMap(emitIncrementally))
}

// реализация довольно тривиальна
// пример вывода: emitIncrementally([0, 1, 2, 3, 4], {batchSize: 2})
// - [0, 1] - сразу же
// - [0, 1, 2, 3] - после таймаута
// - [0, 1, 2, 3, 4] - после очередного таймаута
function emitIncrementally() { ... }
Небольшое уточнение по Angular CDK — он не умеет работать с элементами которые идут колонками (плиткой). В случае если нужна «плитка» можно использовать ngx-virtual-scroller
Как вы выполняете вывод больших списков в своих веб-проектах?

У Вас не будет проблем с большими списками если не будет больших списков) Давайте будем честными, никто в здравом уме не захочет скроллить 3 часа чтобы выбрать 345684132489751324 элемент. Поэтому я пошел по принципу вот вам 10/50/100 первых опции и возможность поиска по списку, как только пользователь начинает вводить что он ищет — подсовываем ему подходящие опции в количестве 10/50/100.
Не во всех случаях возможен такой подход. У нас сотни элементов в коллекции из-за infinity scroll и поменять этот метод на другой не получится — пользователи не оценят от слова вообще
Зарегистрируйтесь на Хабре, чтобы оставить комментарий