Оглавление.

· Безумный вариант использования…
· Проблема с нашим вариантом использования!
· Решение
· API Intersection Observer
Хук useFiestViewportEntry.
Компонент-обертка RenderOnViewportEntry
· Использование
· Заключение

Сегодня React используется для создания приложений, которые с каждым днем ​​становятся все более сложными. Одной из причин этого является его высокая производительность и простота обучения. Другая причина заключается в наличии множества сторонних и общественных библиотек, которые могут обеспечить полезную и красивую функциональность за считанные минуты.

Однако по мере того, как мы внедряем в наши приложения все больше и больше визуально привлекательных функций, нам также необходимо помнить о влиянии указанных функций на производительность.

Сумасшедший вариант использования…

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

Для простоты считайте, что каждый блок здесь представляет собой отдельный компонент, построенный в собственном файле, показывающий простой текст/изображения или чрезвычайно сложные диаграммы или интерактивные таблицы, или данные, которые изменяются в реальном времени на основе некоторых сообщений веб-сокета. Дайте волю своему воображению…

Проблема с нашим вариантом использования!

Когда пользователь посещает наше приложение, все эти компоненты загружаются вместе из-за объединения. Однако окно настольного браузера сможет отображать только определенную часть этого замечательного пользовательского интерфейса, потому что места по вертикали просто недостаточно.

Здесь нижняя половина пользовательского интерфейса приложения скрыта и будет видна нашему пользователю только при прокрутке страницы вниз. В этом случае, даже если пользователю требуются только данные, доступные в компонентах с 1 по 3, все они (1–14) будут отображаться, поскольку они являются частью созданной нами страницы. Это, в свою очередь, вызовет соответствующие API, необходимые для этих компонентов, и, возможно, множество тяжелых библиотек, которые съедят нашу драгоценную обработку.

Решение

Как насчет того, что есть что-то, что может помешать отображению этих компонентов до тех пор, пока пользователь не прокрутит страницу вниз и действительно в них не нуждается.

Отложенная загрузка… На помощь… частично!!

Вместо того, чтобы напрямую импортировать все необходимые компоненты в составной родительский компонент, мы объявляем их лениво импортированными.

И затем в нашем компоненте Dashboard Layout мы можем объявить их в границах приостановки. Это будет извлекать наши отдельные пакеты компонентов только тогда, когда они впервые отображаются на нашей странице, что-то вроде этого.

Здесь Loader — это настраиваемый компонент, который соответствует эстетическим требованиям создаваемого приложения.

Однако это не решает нашей проблемы. Это связано с тем, что все компоненты — даже если они приостановлены — будут извлечены при первом рендеринге, поскольку все границы приостановки будут рендериться при начальной загрузке страницы. На данный момент все, что он делает, это увеличивает количество запросов для нескольких пакетов js! Плохой!

По крайней мере, мы разбили большое беспокойство на множество мелких тревог, прогресс!! Продолжаем.

API-интерфейс наблюдателя за пересечением

Для справки, MDN, конечно!



То, что мы хотим иметь, это что-то вроде этого…

Мы собираемся создать компонент с именем RenderOnViewportEntry, который предотвратит рендеринг нашего компонента, пока он не войдет в область просмотра в первый раз. Мы также хотим, чтобы он обрабатывал состояние загрузки для отката приостановки.

Итак, приступим.

Хук useFirstViewportEntry.

Не вдаваясь в подробности, этот хук берет ref на HTML-элемент и отслеживает его запись в окне просмотра с помощью observerOptions, предоставляемых хост-компонентом, вызывающим хук, просто для дополнительной настройки.

В строке 17–20 мы отключаем наблюдателя, чтобы предотвратить дальнейшую обработку, когда наш элемент покидает область просмотра, поскольку нас интересует только первый раз, когда наш компонент входит в область просмотра. Это изменяет введенную переменную состояния с false на true только один раз.

Компонент-оболочка RenderOnViewportEntry

Здесь мы берем параметры, доступные для Intersection Observer API, в качестве свойств компонента. Опять же для справки, MDN! Это облегчит нам настройку размеров плитки рендеринга.

Мы создаем div и присоединяем к нему ссылку (line16). Мы используем ту же ссылку для перехода к только что созданному хуку, который возвращает состояние, называемое введено.

Мы также разрешаем передавать все реквизиты, разрешенные для элемента div, в div, который мы фактически визуализируем. Это позволит нам настроить отображаемый div. Например, его можно сделать похожим на плитку, как на исходном изображении.

Работает

Поскольку результирующее состояние изначально false и меняется на true только один раз, оно идеально подходит для наших нужд. Мы визуализируем границу приостановки условно на состоянии, возвращаемом хуком, который оборачивает наших дочерних элементов. И поскольку в родительском компоненте мы импортировали дочерние элементы как лениво загруженный компонент, этот компонент будет извлекаться только тогда, когда пользователь прокручивает страницу вниз.

Примечание.Извлечение логики Intersection Observer в отдельный хук в нашем случае на самом деле не было необходимо, но хорошо иметь разделение вещей. И кто знает, может быть, вы найдете другие варианты его использования, кроме отложенной загрузки компонентов…

Применение

Мы обертываем наш ленивый компонент как дочерний элемент RenderOnViewportEntry и предоставляем реквизиты конфигурации. Мы просто должны помнить о двух вещах:

  • Дети должны быть ленивым компонентом.
  • Нам нужно указать минимальную высоту для компонента RenderOnViewportEntry, чтобы он создавал div, который фактически мог увеличить высоту прокрутки страницы, а также позволял порогу работать должным образом.

В следующем примере мы установили 240 пикселей в качестве высоты и порог 0,25, это инициирует выборку Component1, когда div внутри RenderOnViewportEntry находится на 25% в области просмотра. Эти значения будут зависеть от варианта использования. Например, если у вас есть довольно высокий компонент, вы можете использовать меньший порог и так далее.

Заключение

Современные веб-API предлагают нам все больше и больше удивительных вещей каждый день. Все, что нам нужно сделать, чтобы извлечь из них максимальную пользу, — это провести небольшое исследование и выбрать творческий путь для решения проблем.

Наслаждайтесь!!