Я ищу возможность «ленивого рендеринга» с помощью RxJS в Angular, я хочу добиться следующего:
<div *ngFor="let item of items$ | async">
{{item.text}}
<div>
а в компоненте у меня есть:
export class ItemsComponent implements OnInit {
public items$: Observable<Item[]>;
constructor(private setStore: SetStore){}
ngOnInit() {
const setId = 1;
this.items$ = this.setStore.sets$.pipe(map(sets => sets.find(set => set.id = 1).items));
}
}
И это прекрасно работает, но когда в наборе +50 элементов, рендеринг требует времени, и он зависает на секунду или больше. Я искал способ сделать это ленивым, каким-то образом визуализируя первые 30 элементов, а затем загружая следующие 30 через 500 мс и так далее, пока список не достигнет своего конца.
Изменить: я пробовал этот подход:
const _items$ = this.setStore.sets$.pipe(
map(sets => sets.find(set => set.id == 1).items)
);
const loadedItems = [];
_items$.subscribe(data => { this.items$ = from(data).pipe(
concatMap(item => {
loadedItems.push(item);
return of(loadedItems).pipe(delay(1));
})
);
});
})
Вышеупомянутое отлично работает с точки зрения ленивого рендеринга, но имеет некоторые недостатки, такие как:
Приведенные выше коды не тестируются, при необходимости могу предоставить образец
Вы можете использовать виртуальную прокрутку с разными размерами элементов, используя ngx-ui-scroll
демо с элементами переменной высоты начать довольно просто
<div class="viewport">
<div *uiScroll="let item of datasource">
<b>{{item.text}}</b>
</div>
</div>
Насколько я понимаю, вам не хватает дополнительного bufferоператора
А что касается первой пули (начальные элементы), можно пропустить первые 30 delayс.
Если рендеринг занимает так много времени, похоже, что пользовательский интерфейс компонента достаточно сложен, чтобы повлиять на производительность рендеринга - в отличие от простой таблицы. В таком случае вам необходимо ограничить рендеринг (обычно с помощью разбивки на страницы или виртуальной прокрутки).
При использовании Angular лучше всего выбрать CDK Virtual Scroll: https://v9.material.angular.io/cdk/scrolling/overview (v9)
Это очень простая замена * ngFor , но прирост производительности заметен сразу.
Пример:
<div>
<div *ngFor="let item of items" class="example-item">{{item}}</div>
</div>
становится:
<cdk-virtual-scroll-viewport itemSize="100" class="example-viewport">
<div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
ЗАМЕТКА:
Я бы немного изменил ваш код и удалил |asyncреализацию. Для массовой или пакетной обработки ответа я бы предпочел использовать bufferCountоператор, как показано ниже,
ПРИМЕЧАНИЕ . Это фиктивный код, но с его помощью вы можете упростить себе жизнь. В моем примере в результате я получаю массив, в вашем случае это может быть объект или массив объектов (я не знаю);
items = [];
constructor(public httpClient: HttpClient) {
range (1, 30) // total 30 requests
.pipe(
tap(x => {
if(x<=10){
this.items.push(x) // processing 10 requests by default without delay
}
})
).pipe(
skip(10), // skipping already processed 10 requests
bufferCount(10), // processing 10 request in batch
concatMap(x => of(x).pipe(delay(3000)))
).subscribe(result=>{
console.log(result);
this.items = [...this.items, ...result];
})
}
.html
<div *ngFor="let item of items">
{{item}}
</div>
Dummy Demo
Я также согласен с тем, что реализация виртуальной прокрутки будет решением, потому что, если у вас есть 1000 строк, рендеринг в любом случае начнет замедляться, но другой способ снизить стоимость рендеринга - предоставить trackByфункцию вашему @ngforциклу.
Улучшение производительности с отслеживанием
Я обнаружил, что это хорошо работает для меня:
export class AppComponent implements OnInit {
items$: Observable<number[]>; constructor() {} ngOnInit(){ const source$ = from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const items = [];
this.items$ = source$.pipe(
bufferCount(3),
concatMap((items, index) => of(items).pipe(delay(index == 0 ? 0 : 3000))),
map(arr => {
items.push(...arr);
return [...items];
})
);
}
}
Демо
Яна Дуггар открыто говорила о своих поисках любви. Вот все, что она сказала на эту тему и о своем пятилетнем окне для замужества.
Звезда «Чужестранки» Сэм Хьюэн недавно рассказал, что он возьмет со съемочной площадки, чтобы вспомнить Джейми Фрейзера, роль, которая сделала его звездой.
«She Loves You» была написана за час, записана за день и стала песней The Beatles с одним из лучших исполнений в их карьере.
У Долли Партон и ее бабушки Бесси были особые отношения. Бабушка Партон была очень больна, но это не мешало Долли разыгрывать ее.
Вы можете подумать, что дуб или гикори — прочные породы дерева, но когда речь идет о самой твердой древесине в мире, они даже близко не стоят.
Океан полон красоты, но он также скрывает одних из самых страшных морских существ на планете. Многие из этих животных скрываются глубоко под поверхностью океана, в тёмном, полном давления мире морских глубин.
Если вы сражаетесь с враждебными мобами или готовитесь к PvP-боям, знание лучших чар для мечей в Minecraft может дать вам серьёзное преимущество. Зачарование мечей позволяет наносить больше урона, увеличивать количество выпадающих мобов и продлевать срок службы меча.
Когда говорят о социалистических странах, часто представляют себе полный государственный контроль и отсутствие частной собственности. Но на практике социалистические экономики сильно различаются.
В «Детях» появится громкая камео и несколько разрушительных новостей
Утверждается, что этот RAV4 находится в отличном состоянии и готов к игре в музыкальные стулья.
На кадрах, снятых с дрона, видно, как пожарные изо всех сил пытаются потушить пламя.
«Глаза Ваканды» напрямую связаны с MCU, а также обновления о «Людях Икс '97», «Что, если...», «Сорвиголова» и многом другом.
Ава Гарднер была замужем за Микки Руни и Фрэнком Синтрой, и встречалась с несколькими другими голливудскими звездами. Вот взгляд назад на историю знакомств Авы Гарднер.
Джон Клиз женился на Дженнифер Уэйд в 2012 году. Вот все, что нужно знать о жене Джона Клиза, Дженнифер Уэйд.
Олимпийская чемпионка Эллисон Феликс вышла замуж за своего мужа Кеннета Фергюсона в 2018 году. Вот все, что нужно знать о муже Эллисон Феликс, Кеннете Фергюсоне.
Мена Сувари замужем за своим мужем Майклом Хоупом с 2018 года. Вот все, что нужно знать о муже Мены Сувари.
Это поражает меня Внезапно, как это часто бывает, Это снова и снова на полпути <Нет, не то, что в Тихом океане, ты темно-бордовый, то, что на карнавале> Каждый громкий заголовок…..
В 2022 году, с выпуском GPT-3, навыки письма, кажется, стали менее важными. С помощью ИИ люди с плохим письмом также могут генерировать качественный персонал.
В современном быстро меняющемся и конкурентном мире карьера играет важную роль в личностном росте, финансовой стабильности и общей удовлетворенности жизнью. Однако многие люди оказываются в безжалостном цикле застоя и неудовлетворенности, постепенно угасая в своей профессиональной жизни.
На прошлой неделе я заметил пресс-релиз, разосланный через PressGazette (новостной веб-сайт британских СМИ). В статье сообщалось, что Acast, скандинавская компания по размещению и рекламе подкастов, возглавит консорциум «вероятно, самых влиятельных» издателей подкастинга.