Какие способы оптимизации отрисовки большого количества элементов кроме пагинации и infinite scroll
Что проверяют
Понимаете ли вы, где именно тормозит длинный список: во фреймворке, в вёрстке или в браузере. Вопрос сформулирован «кроме пагинации», то есть ждут инструментов уровня рендера, а не продуктового обхода. Дальше просят рассказать, как вы это измеряли.
Как отвечать
Сначала назовите причину: стоимость линейна по числу DOM-узлов и платится трижды, на построении дерева, на пересчёте макета и на отрисовке. Отсюда набор приёмов:
- виртуализация: в DOM живут только видимые строки плюс буфер. Рабочие варианты это TanStack Virtual,
react-virtuoso,react-window. Самописная реализация ломается на переменной высоте строк, готовые меряют её черезResizeObserver; content-visibility: autoвместе сcontain-intrinsic-size: браузер пропускает вёрстку и отрисовку блоков за пределами вьюпорта. Одна строка CSS, но запасной размер обязателен, иначе скроллбар будет прыгать;contain: layout paintна карточке: правка внутри элемента перестаёт пересчитывать весь документ;- меньше работы фреймворка: стабильные
key,React.memoна строке, вынос состояния наведения из стора,useDeferredValueдля поля фильтра, чтобы ввод не ждал перерисовки списка; - перенос вычислений: тяжёлая сортировка и группировка в Web Worker, чтобы главный поток не терял кадры;
- отказ от DOM: если элементов десятки тысяч и они простые, рисуйте на canvas или WebGL, так устроены карты и графики;
- дешевле сами узлы: меньше вложенности на карточку, никаких
box-shadowиfilterна тысячах узлов, анимации только черезtransformиopacity.
Закончите замерами: вкладка Performance, счётчик узлов в Elements, PerformanceObserver по длинным задачам, метрика INP как итог.
Где спотыкаются
Начинают с мемоизации. React.memo спасает от лишних перерисовок, но десять тысяч узлов в DOM останутся десятью тысячами, и скролл продолжит дёргаться.
Советуют will-change на все элементы списка. Каждый такой узел получает свой слой композитора, и вместо ускорения выходит расход видеопамяти и падение кадров.
Называют unstable_batchedUpdates. Начиная с React 18 обновления батчатся автоматически, в том числе внутри промисов и таймеров, совет устарел.