Comments 10
Я использовал что-то типа прогрессивного рендеринга, только триггером был скроллинг. Плюс в том, что не нужно тратить ресурсы на элементы, которые возможно не будут смотреть. Минус — возможно, на некоторых устройствах, скроллинг будет на мгновения подмерзать перед выводом очередной порции данных. Из подводных камней: нужно отлавливать события изменения размеров экрана и проверять размеры контейнера списка, на лету корректировать количество элементов которые нужно вывести. Иначе можно наткнуться на ситуацию когда скроллинг пропал, а все элементы еще не выведены.
Тогда если фантазировать, то можно сделать гибрид по типу рендерим за кадром N элементов, а если пользователь начал скролить, то опять за кадром подгружаем N элементов. Всё равно могут быть проблемы при агрессивном скроллинге, но тоже как решение
Да проблемы особо нет. Скроллинг просто упрется и продолжится когда новая пачка отрисуется. Если такое поведение нормально.
Навскидку — а если скрестить *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.
Sign up to leave a comment.
3 способа рендеринга больших списков в Angular