Включен завершенный код компонента ImageLoader

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

  • Установка react-lazy-load для обработки отложенной загрузки контента.

Пакет React Lazy Load состоит из 1 компонента, который вы используете в React для обтекания содержимого, которое хотите загрузить, только когда вы прокручиваете его. Мы можем определять смещения, как вертикальные, так и горизонтальные, а также настраивать дросселирование и обработчики onContentVisible.

  • Создавая компонент загрузчика изображений, мы назовем ImageLoader для обработки каждого состояния изображения. Почему? response-lazy-load не обрабатывает анимацию перехода при загрузке контента - вместо этого контент просто появляется на экране. Не очень элегантно. Но это нормально, react-lazy-load может сосредоточиться на улучшении своих предложений по загрузке, а мы можем сосредоточиться на способах элегантного представления контента.
  • Создание пользовательских анимаций CSS3 для введения контента и их применение к компоненту ImageLoader. На самом деле response-lazy-load может обрабатывать любой контент, а не только изображения. Кроме того, любой контент может иметь обработчик загрузки, а не только изображения. Поэтому, хотя эта статья посвящена загрузке изображений, вы можете применить эти методы практически к любой разметке HTML.

Реагировать на отложенную загрузку

Пакет response-lazy-load размещен на npmjs и по следующему адресу:
https://www.npmjs.com/package/react-lazy-load

Этот минифицированный пакет на 6 КБ довольно популярен; не достигнув высот гигантов, таких как Redux, но недавно он достиг 90 тысяч загрузок в неделю, а на момент написания - 82 тысячи в неделю.

React Lazy Load - еще одна жемчужина скорости загрузки страницы

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

Важно найти баланс между бюджетом и производительностью. Поэтому, если вы не можете доставлять статические ресурсы со скоростью 10 мс по всему миру с (постоянно улучшающимися) услугами CDN из-за бюджетных ограничений, мы можем быть умнее и ограничить запросы при начальной загрузке страницы. react-lazy-load - один из способов сделать это.

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

Когда речь идет об изображениях, и там, где SVG не хватает, другой эффективный метод оптимизации скорости - создание одного спрайт-листа для всех значков вашего приложения и ссылки на каждый из них как на часть фонового изображения в CSS. Нужна поддержка Retina и поддержка изменения размера элемента? Считайте положение фонового изображения в процентах. Программное обеспечение вроде Texture Packer делает эту работу достаточно эффективно, но для поддержки Retina (процентных спрайтов) нужна платная лицензия.

Насколько важно ограничивать запросы изображений? Что ж, в зависимости от того, где вы находитесь на планете, задержка запроса на изображение (или любой статический актив) запрос может варьироваться от 10 мс (если вы очень близко к серверу ресурсов) до 150–200 мс + (если вы на другой стороне). мира). Добавьте к этому VPN, китайский брандмауэр, если вы находитесь в материковом Китае, и несогласованность общих решений VPS (если вы используете их, а не выделенный сервер), становится необходимостью максимально ограничить запросы до увеличить вероятность этих высоких скоростей загрузки.

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

Помня об этом, давайте добавим react-lazy-load в ваш проект как еще одну ступеньку для быстрой загрузки страниц.

Установка react-lazy-load

Установите с помощью следующей команды, чтобы начать использовать ее в своем проекте.

npm i react-lazy-load

Отсюда импортируйте его в свой проект:

import LazyLoad from 'react-lazy-load';

А чтобы использовать, просто оберните свои изображения в компонент LazyLoad:

<LazyLoad 
      ...
      width={100}
      height={100}
      debounce={false}
      offsetVertical={500}
      >
      <img src="lazy-image.jpg" alt="Lazy Load Example" />
</LazyLoad>

Посмотрите на приведенный выше пример. Давайте перейдем к параметрам смещения и регулирования после быстрого ознакомления с настройками ширины и высоты.

Ширина и высота не являются обязательными, но вы можете использовать их, чтобы заранее определить область, которую ваше изображение будет занимать после загрузки. Но это не на 100% полезно: что, если высота изображения автоматически зависит от ширины для сохранения соотношения сторон? Другими словами,

Как сохранить пространство вокруг не загруженного адаптивного изображения?

Процентное решение заполнения

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

Например, у меня есть изображение размером 1200 пикселей на 675 пикселей (фактически разрешение изображения заголовка этой статьи). Соотношение 1: 0,5625. Давайте воспользуемся знаниями о соотношении сторон изображения, чтобы закодировать CSS, необходимый для поддержания соотношения и поддержки отзывчивости, чтобы он мог элегантно изменять размер:
CSS в этой статье отформатирован в формате SASS, более легкий для чтения синтаксис, чем ванильный CSS. .

.img-container
    width: 100%
    padding-bottom: 56.25%
    position: relative
    background: #fff
    > img
      position: absolute
      top: 0
      left: 0
      width: 100%
      height: auto

И это будет HTML:

<div class="img-container">
    <img src="/my-responsive-image.jpg" />
</div>

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

Теперь наши знания о размещении изображений на высшем уровне, давайте вернемся к react-lazy-load конфигурациям.

Дросселирование и смещение

Параметры дросселирования в LazyLoad могут помочь уменьшить проблемы с производительностью, тогда как смещение позволяет нам загружать содержимое LazyLoad до того, как мы фактически доберемся до него, поэтому, возможно, на 500 пикселей выше или ниже фактического местоположения изображения, используя offsetVertical={500}.

Чтобы взглянуть на регулирование, вернитесь к примеру LazyLoad. Я определил для параметра регулирования debounce значение false:

<LazyLoad 
      ...
      debounce={false}
      throttle={250} //this is the default value of throttle
      ...

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

Чтобы обеспечить единообразие взаимодействия с пользователем, выключите debounce по умолчанию. Если у вас есть проблемы с производительностью, сначала поиграйте с конфигурацией throttle. Throttle определяет тайм-аут между вызовами событий прокрутки LazyLoad, по умолчанию 250 миллисекунд.

Смещение - это еще один способ поддерживать согласованность - мы хотим, чтобы контент был там до того, как пользователь прибудет на место. Доступны offsetTop, offsetLeft, offsetRight и offsetBottom, но на самом деле пользователь может прокручивать страницу снизу или справа, поэтому offsetVertical и offsetHorizontal являются более полезными конфигурациями для использования, поскольку они учитывают оба направления прокрутки в любой ориентации.

onContentVisible также можно использовать для обработки каждой загрузки изображения:

<LazyLoad
    onContentVisible onContentVisible={() => console.log(‘what do you want to do here?’)}
>
...
</LazyLoad>

Вы можете обновить состояние здесь по мере изменения содержимого вашей страницы.

Итак, теперь LazyLoad вставляет наши изображения на место при прокрутке. Но что, если бы мы хотели сделать изображение более привлекательным для пользователя - фактически, применить любую понравившуюся анимацию с помощью анимации по ключевым кадрам CSS3?

Мы можем создать компонент специально для обработки такой функции.

Компонент ImageLoader

Имя ImageLoader прекрасно соответствует назначению этого компонента - он просто обрабатывает загрузку изображений и отслеживает их в своем состоянии. Когда изображение загружается, мы меняем .img-loading класс CSS на класс .img-loaded CSS, позволяя анимации выполняться.

Полный компонент выглядит следующим образом. Копирование и вставка этого в ваш проект будет работать:

Использование этого компонента с LazyLoad выглядит так:

import { ImageLoader } from './ImageLoader.js';
...
<LazyLoad
   ...
 >
    <ImageLoader 
      src="..." //this is the only compulsory prop
      onClick="..."
      ...
     />
</LazyLoad>

Простой, но эффективный компонент, давайте выделим некоторые его особенности:

  • Мы передаем URL-адрес изображения через опору src так же, как в случае с тегом <img/>, начальное состояние загрузки которого хранится в состоянии нашего компонента.
  • У нас есть свойства по умолчанию для класса изображения по умолчанию, классов загрузки и загрузки, поэтому нам не нужно передавать их из родительского компонента, хотя вы можете это сделать.
  • Функция onLoad обрабатывает событие изображения onLoad, обновляя состояние, которое запускает обновление и, следовательно, переключение класса.
  • Я добавил событие onClick, чтобы продемонстрировать дополнительные свойства, которые вы можете передать через ImageLoader. Конкретно, вы можете расширять или изменять этот компонент в соответствии с требованиями вашего проекта.

После импортирования этого компонента просто замените свой <img src… /> JSX на <ImageLoader src… /> JSX.

CSS-анимации

В приведенном выше примере у нас есть классы .img-loading и .img-loaded. Эти классы обрабатывают простое постепенное появление с изменением прозрачности:

@keyframes fadeInImg
 from
  opacity: 0
 to
  opacity: 1

.img-loading
   opacity: 0
   width: 100%
   height: auto
.img-loaded
   animation: fadeInImg cubic-bezier(0.23, 1, 0.32, 1) 1
   position: relative
   opacity: 0
   animation-fill-mode: forwards
   animation-duration: 0.7s
   animation-delay: 0.1s

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

  • Для более сложной анимации: внутри fadeInImg переключите to и from на 0% и 100% и добавьте больше ключевых кадров в различных процентах, чтобы добавить больше состояний к анимации.
  • Добавьте к анимации дополнительные свойства. Например, тонкое преобразование масштаба с transform: scale(1.02,1.02) на transform: scale(1,1). Поворот также можно настроить с помощью преобразования.
  • Может быть достигнут тонкий эффект падения, от top: -3px до top: 0px.
  • Поиграйте со свойствами анимации, чтобы улучшить входы в изображения.

Заключение

В этой статье мы довольно много рассказали о важности скорости страницы и ее связи с загрузкой изображений, а также о реализации одного решения в React на пути к более быстрому взаимодействию с пользователем с использованием response-lazy-load.

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

Задача: добавьте дополнительные состояния загрузки в ImageLoader и объедините несколько классов анимации вместе!