Оптимизация изображений в NextJS

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

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

К концу этой статьи вы должны понять следующие концепции:

  • Оптимизация изображения
  • Использование next/image
  • Реквизиты изображения
  • Настройка next.config.js
  • Использование собственного тега < img > в NextJS

Оптимизация изображений

Обычно, если вы собираетесь использовать изображение на своем сайте/приложении, вы делаете следующее (при условии, что изображение находится в той же директории, что и веб-страница, к которой оно обращается):

<img src="./apple.jpg">
Войдите в полноэкранный режим Выйти из полноэкранного режима

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

<img src="./apple.jpg" alt="Image of an apple"/>
Войти в полноэкранный режим Выйти из полноэкранного режима

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

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

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

Поэтому NextJS предоставляет нам встроенный API оптимизации изображений, next/image, каноническую форму для встроенной автоматической оптимизации изображений.

Использование next/image

Компонент Image в NextJS очень похож на родной html <img>, он является расширением этого элемента и может быть использован путем импорта из next/image и использования его, как вы бы использовали компонент с props.

import Image from 'next/image';

export default function SampleImage({source}) {
    return (
        <div>
            <Image src={source} alt='Image alt text'/>
        </div>
    )
} 

Вход в полноэкранный режим Выход из полноэкранного режима

Тег Image имеет несколько реквизитов, доступных для использования помимо src и alt, мы рассмотрим некоторые из них

width и height реквизит

Ширина и высота изображения указывается в пикселях, при добавлении ширины и высоты убедитесь, что добавлены правильные размеры. Если добавлено другое соотношение сторон, изображение будет соответствующим образом скорректировано. Например, если изменить ширину и высоту изображения (1400 x 700) на (400 x 400), как показано ниже, это может привести к перекосу изображения.

import Image from 'next/image';

export default function SampleImage({source}) {
    return (
        <div>
            <Image 
               src={source} 
               alt='Image alt text'
               height={400}
               width={400}
             />
        </div>
    )
} 
Вход в полноэкранный режим Выход из полноэкранного режима

Свойство layout

Бывают случаи, когда вы не знаете ширину и высоту изображения, но хотите, чтобы оно заполнило все пространство, сохранив при этом соотношение сторон. В такой ситуации можно не указывать ширину и высоту компонента Image. Вместо этого добавьте параметр layout="fill". Это растянет изображение на ширину и высоту родительского элемента. При использовании свойства layout="fill" часто лучше всего использовать его в паре с objectFit="cover". Это позволит изображению сохранить соотношение сторон и заполнить все поле содержимого элемента.
Чтобы добиться этого, оберните компонент Image как дочерний элемент элемента <div>. Затем добавьте ширину и высоту к родительскому элементу <div>, а также задайте ему position="relative".

import Image from 'next/image';

export default function SampleImage({source}) {
    const myStyle = {
       height: '400px',
       width: '400px',
       position: 'relative' 
   }
    return (
        <div style={myStyle}>
            <Image 
               src={source} 
               alt='Image alt text'
               layout='fill'
               objectFit='cover'
             />
        </div>
    )
} 

Вход в полноэкранный режим Выход из полноэкранного режима

Таким образом, мы видим, что изображение занимает 400-пиксельный квадрат, который мы хотели, но соотношение сторон изображения сохраняется. Части изображения, которые не помещаются в родительский элемент, обрезаются.

Другие значения layout — intrinsic, fixed и responsive.

loader prop

Загрузчик — это функция, возвращающая строку URL для изображения, учитывая следующие параметры (src, width, quality). Установка загрузчика в качестве параметра компонента Image переопределяет загрузчик по умолчанию, определенный в разделе images в next.config.js.

import Image from 'next/image'

const sampleLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

const MyImage = (props) => {
  return (
    <Image
      loader={sampleLoader}
      src="me.png"
      alt="My Picture"
      width={500}
      height={500}
    />
  )
}
Вход в полноэкранный режим Выход из полноэкранного режима

Свойство sizes

Вы можете указать список ширины изображений с помощью свойства images.imageSizes в вашем файле next.config.js. Эти ширины объединяются с массивом размеров устройств для формирования полного массива размеров, используемых для генерации srcsets изображений.

module.exports = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}
Вход в полноэкранный режим Выход из полноэкранного режима

Или определив его в своем компоненте, например,

<Image
    src={src}
    alt="image-alt-text"
    sizes="320 640 700"
    layout="responsive"
/>
Войти в полноэкранный режим Выйти из полноэкранного режима

Помните, что рекомендуется определять sizes только при использовании макета responsive или fill.

Свойство quality.

Качество оптимизированного изображения, целое число от 1 до 100, где 100 — наилучшее качество. По умолчанию установлено значение 75.

<Image
    src={src}
    alt="image-alt-text"
    quality={100}
    layout="fill"
/>
Переход в полноэкранный режим Выход из полноэкранного режима

priority prop

По умолчанию изображения не имеют приоритетов (поскольку они загружаются в ленивом режиме), поэтому приоритет по умолчанию false. Когда true, изображение считается высокоприоритетным и предварительно загружается.
Вы должны использовать свойство priority для любого изображения, обнаруженного как элемент Largest Contentful Paint (LCP).
Должно использоваться только в том случае, если изображение видно выше сгиба. По умолчанию false.

<Image
    src={src}
    alt="image-alt-text"
    width={500}
    height={300}
    priority
/>
Войти в полноэкранный режим Выход из полноэкранного режима

placeholder prop

Это свойство placeholder используется в качестве резервного изображения при загрузке изображения. Его возможные значения: blur или empty.
Если empty, то во время загрузки изображения не будет никакого заполнителя, только пустое пространство. Если blur, то свойство blurDataURL будет использоваться в качестве заполнителя. Если src является объектом из статического импорта и импортированное изображение имеет формат .jpg, .png, .webp или .avif, то свойство blurDataURL будет заполнено автоматически.

<Image
    src={src}
    alt="image-alt-text"
    width={500}
    height={300}
    placeholder="blur"
/>
Вход в полноэкранный режим Выход из полноэкранного режима

Свойство blurDataURL

Реквизит blurDataURL — это изображение-заполнитель, которое загружается до успешной загрузки изображения src. Это должно быть изображение URL данных в base64-кодировке, которое действует только при использовании в сочетании с placeholder="blur".

<Image
  src={src}
  alt="image-alt-text"
  width={600}
  height={450}
  placeholder="blur"
  blurDataURL=data:image/png;base64,[IMAGE_CODE_FROM_PNG_PIXEL]”
/>
Вход в полноэкранный режим Выход из полноэкранного режима

Свойство objectFit

Свойство objectFit определяет, как изображение будет помещаться в контейнер родителя, аналогично свойству object-fit CSS. Он используется с layout=fill или изображением с заданными width и height.

<Image 
    src={src}
    alt="image-alt-text"
    layout="fill"
    objectFit="contain"
/>
Вход в полноэкранный режим Выйти из полноэкранного режима

Имеет следующие возможные значения: contain, cover, fill, none и scale-down.

unoptimized prop

Если true, исходное изображение будет передаваться как есть вместо изменения качества, размера или формата. По умолчанию false.

<Image
    src={src}
    alt="image-alt-text"
    width={700}
    height={450}
    unoptimized
/>
Войти в полноэкранный режим Выход из полноэкранного режима

Настройка next.config.js

Вы можете настроить изображение NextJS через файл next.config.js.

domains

При использовании внешнего URL для загрузки изображений, вы должны добавить его в domains в next.config.js.

module.exports = {
    images: {
        domains: ['example.com'],
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

loader

По умолчанию NextJS занимается оптимизацией изображений, но вы можете передать эту ответственность облачному провайдеру, такому как Cloudinary или imgix, который больше занимается изображениями, чем общей оптимизацией.

module.exports = {
    images: {
        loader: 'cloudinary',
        path: 'https://your-site.com/assets/images/'
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Помните, что когда loader установлен на внешний сервис изображений, конфигурация domains игнорируется.

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

Заключение

Оптимизация изображений в Next.js улучшает работу пользователей и разработчиков, но, как и любая другая вещь в программировании, компонент Image имеет некоторые ограничения, одним из которых является его неспособность корректировать CSS напрямую. В отличие от родного элемента <img>, которому можно передать свойство style, чтобы переопределить его CSS. Компонент изображения NextJS вообще не поддерживает свойство style. Поэтому, чтобы придать стиль исходному изображению, назовите его className, а затем нацельте на него свой CSS.

<Image
    src={src}
    alt="image-alt-text"
    width={700}
    height={450}
    className="myImage"
/>
Вход в полноэкранный режим Выход из полноэкранного режима

P.S.: Next.js заставляет использовать свой компонент вместо родного тега <img> путем включения соответствующей проверки линтера в процесс сборки приложения. Поэтому, если вы собираетесь использовать тег <img> в приложении NextJS, вы должны добавить следующее, чтобы отключить проверку

// eslint-disable-next-line @next/next/no-img-element
 <img
     src={src}
     alt='myImg'
     className='myImage'
 />
Войти в полноэкранный режим Выйти из полноэкранного режима

Или добавив "@next/next/no-img-element": "off" в файл .eslintrcconfig.

Надеюсь, вам понравилось читать эту статью так же, как мне понравилось ее писать, и вы как можно скорее создадите свое приложение на NextJS.

Использованные ресурсы:

  • NextJS Doc
  • Log Rocket
  • UploadCare
  • Level Up Coding

👉🏾 Узнайте больше обо мне

👉🏾 Подключайтесь на LinkedIn

👉🏾 Подпишитесь на мой блог, давайте пировать

Оцените статью
Procodings.ru
Добавить комментарий