JavaRush /Курсы /Модуль 3: React /Оптимизация списков с React.Virtualized

Оптимизация списков с React.Virtualized

Модуль 3: React
10 уровень , 6 лекция
Открыта

Почему оптимизация списков так важна?

Современные приложения часто работают с большими объёмами данных. Например, бесконечная лента в соцсетях, списки пользователей или результаты поисковых систем. Если отрендерить все элементы списка сразу, то браузер, скорее всего, падёт под тяжестью DOM-узлов, а пользователь заварит себе третью чашку кофе, пока страница грузится.

Задача проста: рендерить только ту часть списка, которую пользователь видит на экране. Здесь на помощь и приходит библиотека React.Virtualized. Она позволяет создавать виртуализированные списки, рендеря только видимые элементы, а остальные "держит в кэше" до тех пор, пока они не потребуются.

Давайте представим: ваш список содержит 10 000 элементов. Даже если каждый элемент небольшой и весит 1 кБ, браузеру потребуется создать и держать в памяти 10 000 DOM-узлов. Вот несколько проблем, с которыми вы столкнётесь:

  • Падение производительности. Браузер будет с трудом обновлять интерфейс, особенно если список динамически изменяется.
  • Долгая загрузка страницы. Пользователь увидит белый экран, пока весь список создаётся.
  • Проблемы с памятью. Браузер может просто зависнуть из-за недостатка ресурсов.

Всё это приводит к плохому пользовательскому опыту и низкой скорости работы приложения. С помощью React.Virtualized мы сможем избавиться от этих проблем, рендеря только видимые элементы.

Знакомство с React.Virtualized

Для начала установим библиотеку:

npm install react-virtualized

Это библиотека, специально созданная для работы с большими списками, таблицами и сетками.

Основные компоненты React.Virtualized

  • List: рендерит виртуализированный список.
  • Grid: позволяет рендерить элементы в виде сетки.
  • AutoSizer: автоматически определяет размеры контейнера.
  • CellMeasurer: помогает измерять размеры ячеек, если их содержимое динамическое.

Сегодня мы сосредоточимся на List — самом популярном компоненте.

Пример использования List

Давайте создадим приложение с длинным списком и оптимизируем его с помощью React.Virtualized. Допустим, у нас есть массив из 10 000 элементов:

Шаг 1: Базовый список без оптимизации

Вот как это может выглядеть:

import React from 'react';

const items = Array.from({ length: 10000 }, (_, idx) => `Item ${idx + 1}`);

const SimpleList: React.FC = () => {
  return (
    <div>
      {items.map((item) => (
        <div key={item} style={{ padding: '10px', border: '1px solid #ccc' }}>
          {item}
        </div>
      ))}
    </div>
  );
};

export default SimpleList;

Этот код создаёт список из 10 000 элементов. Но если вы запустите его в браузере, то сразу заметите: всё тормозит! Вот где React.Virtualized вступает в игру.

Шаг 2: Использование List из React.Virtualized

Давайте перепишем этот код, добавив виртуализацию:

import React from 'react';
import { List, ListRowRenderer } from 'react-virtualized';
import 'react-virtualized/styles.css'; // Стили для работы List

const items = Array.from({ length: 10000 }, (_, idx) => `Item ${idx + 1}`);

const VirtualizedList: React.FC = () => {
  // Шаг 1: Функция для рендера строки списка
  const rowRenderer: ListRowRenderer = ({ index, key, style }) => (
    <div key={key} style={style}>
      {items[index]}
    </div>
  );

  return (
    // Шаг 2: Компонент List
    <List
      width={800} // Ширина списка
      height={600} // Высота списка (окно просмотра)
      rowCount={items.length} // Общее количество элементов
      rowHeight={50} // Высота одной строки
      rowRenderer={rowRenderer} // Функция рендера строки
    />
  );
};

export default VirtualizedList;

Объяснение кода

  1. rowRenderer — это функция, которая отвечает за рендеринг одной строки списка. Она принимает параметры:

    • index — индекс элемента в массиве.
    • key — уникальный ключ элемента (важно для производительности).
    • style — стили для строки (например, чтобы позиционировать её правильно).
  2. List — это сам компонент списка:

    • width и height задают размеры окна просмотра viewport.
    • rowCount указывает общее количество элементов.
    • rowHeight задаёт фиксированную высоту строки.

Дополнительные возможности React.Virtualized

Окей, мы сделали базовый виртуализированный список. Но что, если:

  1. Высота элементов списка разная?

    Для работы с разноразмерными элементами используется компонент CellMeasurer. Он автоматически измеряет высоту строки и передаёт её в List.

  2. Контейнер гибкий, и его размеры меняются?

    В этом случае можно использовать AutoSizer. Этот компонент автоматически определяет ширину и высоту списка.

Пример с AutoSizer:

import React from 'react';
import { List, AutoSizer } from 'react-virtualized';

const items = Array.from({ length: 10000 }, (_, idx) => `Item ${idx + 1}`);

const AutoSizedList: React.FC = () => {
  const rowRenderer = ({ index, key, style }: any) => (
    <div key={key} style={style}>
      {items[index]}
    </div>
  );

  return (
    <AutoSizer>
      {({ width, height }) => (
        <List
          width={width} // Ширина определяется автоматически
          height={height} // Высота тоже
          rowCount={items.length}
          rowHeight={50}
          rowRenderer={rowRenderer}
        />
      )}
    </AutoSizer>
  );
};

export default AutoSizedList;

Преимущества React.Virtualized

  1. Экономия памяти. DOM содержит только те элементы, которые видимы.
  2. Ускорение загрузки. Список рендерится быстрее, так как не требуется создавать весь массив DOM-узлов.
  3. Гибкость. Можно легко комбинировать с другими компонентами, такими как Grid для таблиц или AutoSizer для адаптации под экран.

Типичные ошибки и сложности

  • Неправильное использование стилей. Не забывайте, что style, передаваемый в rowRenderer, обязателен! Он определяет позицию элемента.
  • Сложный рендеринг в rowRenderer. Если rowRenderer делает слишком много вычислений, это негативно повлияет на производительность.
  • Неподходящие размеры окна. Следите за тем, чтобы width и height указывали реальный viewport.

Реальное применение

Вы уже догадались, что оптимизация списков с React.Virtualized пригодится, если вы работаете с:

  1. Лентами новостей.
  2. Таблицами с тысячами строк.
  3. Любыми приложениями с бесконечными списками данных.

Теперь вы готовы добавить виртуализацию в любые свои проекты и заставить большие списки летать, словно они состоят из трёх элементов!

1
Задача
Модуль 3: React, 10 уровень, 6 лекция
Недоступна
Создание базового виртуализированного списка
Создание базового виртуализированного списка
1
Задача
Модуль 3: React, 10 уровень, 6 лекция
Недоступна
Адаптивный виртуализированный список с использованием AutoSizer
Адаптивный виртуализированный список с использованием AutoSizer
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ