Админка отдаёт 50 тысяч строк, вы выводите их в разметку как есть, и скролл захлёбывается. По замерам из разбора такой список стоит браузеру около 850 МБ узлов DOM против 1,2 МБ у той же таблицы с виртуализацией.
Живыми остаются только 15–20 видимых строк, остальное лежит массивом в JS. При скролле вы не создаёте и не удаляете узлы, а переиспользуете те же: меняете текст и сдвигаете.
Дальше два шага. Первый: невидимый div высотой «число строк × высота строки», иначе скроллбар считает список коротким. Второй: строке ставится
top: index × ITEM_HEIGHT, иначе двадцатитысячная строка нарисуется у верхней кромки.Забрал бы этот разбор на случай, когда в списке заводится бесконечная прокрутка: весь путь показан на чистом JS. Ограничение видно из формул: они держатся на фиксированной высоте строки.
#фронтенд
