Оптимизация рендеринга больших таблиц: почему CSS grid не всегда спасает и как помочь PHP

BOptionsB — торговые сигналы для бинарных опционов
Новичок
Статус
Оффлайн
Регистрация
2 Окт 2026
Сообщения
1
Реакции
0
Недавно столкнулся с классической, на первый взгляд, задачей: вывести на внутреннем портале огромную таблицу данных (около 15 000 строк) с динамической фильтрацией. Казалось бы, 2024 год на дворе, но браузеры всё так же «выпадают в осадок», если пытаться скормить им такой объём в лоб через стандартный table. Делюсь опытом, как разрулил это на стыке PHP и CSS без привлечения тяжелых JS-фреймворков.

Проблема семантики и производительности​

Первая ошибка, которую совершают многие — использование display: table для сложных макетов. Когда у вас тысячи ячеек, браузер тратит колоссальное время на расчет геометрии каждой колонки, ориентируясь на содержимое. Я перешел на CSS Grid. Это дает контроль над отрисовкой: можно жестко задать grid-template-columns, и браузеру не придется пересчитывать ширину всей таблицы при загрузке каждой новой строки.
Однако, даже с гридами 15 тысяч DOM-узлов — это перебор. Память течет, скролл лагает. Решение пришло со стороны виртуализации, но реализованной максимально просто. Вместо того чтобы выплевывать весь массив из PHP, я внедрил постраничную подгрузку через Intersection Observer API, но с одной хитростью в CSS.

CSS-хак для стабильного скролла​

Чтобы полоса прокрутки не прыгала при подгрузке новых данных, я использовал свойство contain-intrinsic-size вместе с content-visibility: auto. Это позволяет браузеру пропускать рендеринг элементов, которые находятся за пределами вьюпорта, при этом сохраняя их «виртуальное» место в разметке. Контейнер таблицы не схлопывается, и пользователь не теряет фокус.

Оптимизация на стороне бэкенда (PHP)​

На стороне PHP основной затык был в потреблении памяти при формировании JSON-ответа. Стандартный PDO::fetchAll() на таких объемах — это гарантированный Out of Memory. Переписал логику на использование генераторов (yield). Это позволило стримить данные из базы порциями, не забивая RAM сервера. Кстати, если вам интересно, как эффективно работать с памятью в высоконагруженных скриптах, советую глянуть архитектурных паттернов для обработки очередей, там много пересекающихся моментов по части ресурсов.

Практические выводы​

  • Забудьте про <table> для данных свыше 2000 строк. Только div с display: grid. Это в разы ускоряет начальный рендеринг (First Contentful Paint).
  • Используйте content-visibility. Это реально «серебряная пуля» для длинных списков в современных браузерах (Chrome 85+, Edge).
  • Никаких тяжелых вычислений в цикле вывода PHP. Все преобразования дат, форматирование валют и прочее должны быть сделаны на уровне SQL-запроса или кэшированы.
В итоге удалось добиться плавного скролла и мгновенного отклика интерфейса при фильтрации. Главный инсайт: производительность фронтенда часто начинается с того, как вы спроектировали отдачу данных на бэкенде. Если PHP отдает «жирный» объект, никакой CSS не спасет от лагов при парсинге DOM.
 
Назад
Верх Низ