Бесконечный скроллинг в ReactJS: проработка высокой производительности
Быстрый ответ
Для внедрения бесконечной прокрутки в React рекомендуется использовать IntersectionObserver
для отслеживания событий прокрутки и react-window
для оптимизированного отображения списков. Размещайте два "наблюдателя" на обоих концах списка и начинайте подгрузку данных при активации прокрутки. Благодаря react-window
, рендерится только видимая часть элементов, что повышает производительность.
Вот наглядный пример кода:
import { FixedSizeList as List } from 'react-window';
function useInfiniteScroll(loadMoreItems) {
useEffect(() => {
const options = { /* ... параметры ... */ };
const topObserver = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) loadMoreItems('top');
}, options);
const bottomObserver = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) loadMoreItems('bottom');
}, options);
topObserver.observe(document.getElementById('top-sentinel'));
bottomObserver.observe(document.getElementById('bottom-sentinel'));
return () => {
topObserver.disconnect();
bottomObserver.disconnect();
};
}, []);
}
const InfiniteLoader = ({ loadMoreItems }) => {
useInfiniteScroll(loadMoreItems);
return (
<List height={300} itemCount={1000} itemSize={35} width={300}>
{({ index, style }) => (
<>
{index === 0 && <div id="top-sentinel"></div>}
<div style={style}>Элемент {index}</div>
{index === 999 && <div id="bottom-sentinel"></div>}
</>
)}
</List> // Всего 1000 элементов в списке
);
};
Функция loadMoreItems
обязана подгружать данные как сверху, так и снизу списка. Настройки FixedSizeList
адаптируйте под свои цели. Этот подход сочетает в себе производительность и плавность бесконечной прокрутки.
Оптимизация производительности и рендеринга
Стратегия плавной прокрутки
Важно гарантировать плавность прокрутки, особенно когда в списке перевалило за 10 тысяч элементов. Тщательное измерение высоты элементов и использование событий onload
для динамического корректирования размеров поможет избежать подпрыгиваний.
// Следим за высотой элементов в компоненте списка с помощью `onload`
const ItemComponent = ({ src }) => {
const ref = useRef(null);
useEffect(() => {
if (ref.current) {
const height = ref.current.offsetHeight;
// storeElementHeight(index, height); // Функция для отслеживания высоты
}
}, [src]);
return <img ref={ref} src={src} onLoad={() => {/* Обработка загрузки */}} alt="" />;
};
Управление состоянием в React
Сокращайте использование состояний в React, отслеживанте начальный индекс и количество на экране отображаемых элементов, и обновляйте список в соответствии с изменяющимися данными прокрутки.
Обработка элементов с переменной высотой
При наличии элементов с переменной высотой используйте react-variable-height-infinite-scroller
для плавной прокрутки. Для обеспечения сохранности отрисовки присваивайте элементам уникальные ключи и корректируйте положение прокрутки в зависимости от высоты элементов, используя состояние или контекст.
Изучение библиотек компонентов
Рассмотрите такие ресурсы, как react-data-grid
для редактирования и интеграции постепенной подгрузки. Визитите сайт http://react.rocks/ — широкий выбор компонентов и материалов.
Визуализация
Бесконечная прокрутка в обе стороны — это словно путешествие по миру контента, которое улучшает восприятие пользователем.
Ниже показано, как это работает:
|---🔄---|
| <-[📄📄📄] -> | # Готовы к прокрутке! С двух сторон контент на подходе.
Прокрутка вверх:
|---🔄---|
| <-[📄📄📄📄📄] -> | # Появляется контент, который вы еще не видели.
Прокрутка вниз:
|---🔄---|
| <-[📄📄📄📄📄] -> | # Открывается новый контент.
Бесконечное путешествие:
|---🔄---|
| <-[...📄📄📄📄📄...] -> | # Бесконечность, прокрутка не имеет конца...
Контент подгружается вовремя, как горячая пицца от курьера — пользователю не видно границ.
Поддержание целостности списка и максимальной производительности
Использование пустых div-ов
Добавьте большой пустой div в начало списка, чтобы создать ощущение присутствия предыдущих элементов.
Применение троттлинга и дебаунсинга
Применяйте дебаунсинг и троттлинг к событию прокрутки, чтобы предотвратить лишние операции отрисовки и обновлений состояний, которые могут понизить производительность.
Сохранение позиции прокрутки
При перезагрузке страницы или при перемещении по сайту сохраняйте позицию прокрутки, чтобы пользователь вернулся к тому месту, где он остановил свое бесконечное путешествие.
Полезные материалы
- GitHub – bvaughn/react-virtualized: React components for efficiently rendering large lists and tabular data — эффективная отрисовка больших списков и табличных данных в React.
- react-window — оптимизация отображения элементов для бесконечной прокрутки.
- Интерфейс API наблюдения за пересечениями – Веб-апи | MDN — основы работы с API для реализации бесконечной прокрутки.
- Как создать компонент бесконечной прокрутки в React с использованием Хуков — подробное руководство по созданию бесконечной прокрутки с Хуками React.
- Объяснение Дебаунсинга и Троттлинга через Примеры | CSS-Tricks — дебаунсинг и троттлинг ипользуемые в прокрутке, представлены на понятных примерах.
- React Patterns — современные паттерны React для решения разнообразных задач.