← Назад к вопросам

Не будет ли зависать Frontend при получении 100000 строк в таблице

2.0 Middle🔥 182 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Будет ли зависать фронтенд при получении 100 000 строк в таблице?

Короткий ответ: да, с высокой вероятностью зависнет или будет работать крайне медленно, если реализовать наивный рендеринг всех строк сразу. Проблема не столько в получении данных (хотя и это может быть проблемой), сколько в их обработке, рендеринге и управлении DOM. Современные браузеры и JS-движки способны обрабатывать большие объемы данных в памяти, но отрисовка 100 000 DOM-элементов одновременно почти наверняка приведет к критическим проблемам с производительностью.

Ключевые проблемы при рендеринге 100 000 строк

  1. Объем DOM-дерева: Каждая строка таблицы (<tr>) содержит несколько ячеек (<td>). Для 100 000 строк и, допустим, 5 колонок, браузеру нужно создать и поддерживать минимум 500 000 элементов. Это огромная нагрузка на память и механизмы рефлоу/репаза.
  2. Блокировка основного потока: Рендеринг такого количества элементов займет сотни миллисекунд или даже секунды. На это время основной поток JavaScript будет заблокирован, что приведет к "заморозке" интерфейса — пользователь не сможет скроллить, кликать или видеть индикаторы загрузки.
  3. Потребление памяти: Каждый DOM-узел потребляет значительный объем памяти. При 100 000 строк потребление может легко превысить сотни мегабайт, что может привести к крашу вкладки на слабых устройствах.
  4. Производительность скроллинга: Даже если таблица отрисуется, попытка прокрутить такой список будет крайне заторможенной, так как браузер будет постоянно пересчитывать видимую область и стили для тысяч элементов.

Правильные стратегии решения

Для работы с большими объемами данных на фронтенде существуют специальные техники и библиотеки. Вот основные подходы:

1. Пагинация

Самый простой и распространенный способ — разбить данные на страницы.

// Пример логики пагинации на клиенте (если данные уже загружены)
const itemsPerPage = 50;
const currentPage = 1;

function renderPage(data, page) {
  const start = (page - 1) * itemsPerPage;
  const end = start + itemsPerPage;
  const pageData = data.slice(start, end);
  // ... рендерим только pageData (50 строк)
}

Преимущества: Простота реализации, низкая нагрузка на браузер. Недостаток: Пользователь не видит все данные сразу и не может выполнить клиентский поиск по полному набору (если данные не загружены целиком).

2. Бесконечный скролл (Infinite Scroll)

Постепенная подгрузка данных по мере прокрутки пользователя.

// Упрощенный пример с Intersection Observer API
const observer = new IntersectionObserver((entries) => {
  if (entries[0].isIntersecting) {
    loadMoreData(); // Загружаем следующую порцию
  }
}, { threshold: 1.0 });

observer.observe(document.querySelector('#loadTrigger'));

3. Виртуализация (Virtualization) — НАИБОЛЕЕ ЭФФЕКТИВНОЕ РЕШЕНИЕ

Это ключевая технология для работы с огромными списками. Рендерятся только те элементы, которые видны в viewport (окне просмотра), плюс несколько запасных строк сверху и снизу для плавного скролла.

// Пример использования библиотеки react-window для React
import { FixedSizeList as List } from 'react-window';

const Row = ({ index, style }) => (
  <div style={style}>Row {index}</div>
);

const VirtualizedList = () => (
  <List
    height={600}
    itemCount={100000}
    itemSize={35}
    width={'100%'}
  >
    {Row}
  </List>
);

Как это работает:

  • Высота всего списка вычисляется как itemCount * itemSize (например, 100 000 * 35px = 3 500 000px).
  • При скролле библиотека вычисляет, какие индексы элементов (startIndex, endIndex) должны быть видны.
  • В DOM рендерятся только эти элементы (например, 20-30 штук), остальные существуют лишь как данные в памяти.
  • Позиция видимой области имитируется с помощью CSS-трансформаций или абсолютного позиционирования.

Популярные библиотеки для виртуализации:

  • React: react-window, react-virtualized.
  • Vue: vue-virtual-scroller, vue-virtual-scroll-grid.
  • Angular: @angular/cdk/scrolling.
  • Vanilla JS: TanStack Virtual (ранее react-virtual), отлично работает с любым фреймворком.

4. Отложенный рендеринг (Deferred Rendering)

Использование setTimeout, requestIdleCallback или setImmediate для разбиения рендеринга на небольшие задачи, не блокирующие основной поток надолго.

async function renderLargeDataSet(data, chunkSize = 100) {
  for (let i = 0; i < data.length; i += chunkSize) {
    const chunk = data.slice(i, i + chunkSize);
    // Рендерим чанк
    renderChunkToDOM(chunk);
    // "Отдаем" контроль основному потоку на кадр анимации
    await new Promise(resolve => setTimeout(resolve, 0));
  }
}

Рекомендации по архитектуре

  1. Обсудить с бэкендом: Всегда ли нужны все 100 000 строк? Часто проблема решается на уровне API: добавить пагинацию, фильтрацию и поиск на сервере.
  2. Загружать по мере необходимости: Не загружать весь массив сразу. Использовать пагинацию на бэкенде или курсоры для постраничной потоковой загрузки.
  3. Использовать Web Workers: Если необходима сложная обработка полученного массива (сортировка, фильтрация) — вынести ее в отдельный поток, чтобы не блокировать интерфейс.
  4. Мемоизация и useMemo: В React-приложениях обязательно использовать React.memo, useMemo, useCallback для компонентов строк, чтобы избежать лишних ререндеров.
  5. Деструктуризация таблицы: Рассмотреть альтернативные способы представления данных — графики, сводные таблицы, агрегированные показатели. Возможно, пользователю не нужен именно посточный просмотр.

Заключение

Получение 100 000 строк на фронтенд — нормальная практика для многих enterprise-приложений (отчеты, аналитика, логи). Ключ к успеху — никогда не рендерить их все одновременно в DOM.

Оптимальный стек решений:

  1. Бэкенд-пагинация для первоначальной загрузки.
  2. Виртуализированная таблица на фронтенде для отображения.
  3. Web Workers для тяжелых вычислений с этими данными.
  4. Эффективное кэширование загруженных данных (например, с помощью TanStack Query).

Таким образом, при правильной архитектуре фронтенд не только не зависнет, но и будет обеспечивать плавный, отзывчивый интерфейс при работе с миллионами записей.

Не будет ли зависать Frontend при получении 100000 строк в таблице | PrepBro