Дата: 22.07.22 Тикет: ...
Референс - https://nextjs.org/docs/api-reference/next/image
- Компонент рендерит тег
imgвspanэлементе, сохраняются пропорции по рецепту из https://css-tricks.com/aspect-ratio-boxes/#aa-the-core-concept-padding-in-percentages-is-based-on-width - Ссылки на изображение оборачиваются в
imgproxy - Для статически импортируемого изображения автоматически вычисляются
widthиheight - По умолчанию и для
layout="fixed", генерируетсяsrc-setс обычным иx2изображением - Для
layout="responsive"иlayout="fill"генерируетсяsrc-setна основе дефолтныхdeviceSizesДефолтное значение свойстваdeviceSizes-[720, 828, 1366, 1920, 3840], основанное на популярных на tinkoff.ru разрешениях экрана - При передаче свойства
deviceSizes, например[400, 800], генерируетсяsrc-setс размерами400w, 800w. Ширина ограничена вариантами из списка ... - По умолчанию тег
imgимеет атрибутloading="lazy", убираем при наличии пропсаpriority="hight" - По умолчанию качество сжатия в
imgproxy-70, при наличии пропсаquality="hight"меняем на95 - Для
startиstart-prodсборки и тестов не используетсяimgproxy
Про дефолтные deviceSizes, с учетом аналитики пользователей tinkoff.ru:
720 - покрывает самое популярное разрешение, 360px, x2 для retina дисплеев 828 - покрывает четыре следующих популярных разрешений, 414px самое большое из них, x2 для retina дисплеев 1366 - относительно популярное десктоп разрешение, покрывает менее популярное 1280 разрешение, оставляем как промежуточный вариант 1920 - самое популярное десктоп разрешение, покрывает менее популярные 1536 и 1440 разрешения 3840 - самое популярное десктоп разрешение, x2 для retina дисплеев
-
src- ссылка на изображение форматов.png,.jpegили.webp. Может быть получена статическим импортом изображения, тогда не требуетсяwidthиheightилиaspectRatio. -
width? - строка с шириной изображения (обязательно если не статический импорт?) -
height? - строка с высотой изображения (обязательно если не статический импорт?) -
aspectRatio? - строка, css свойствоaspect-ratioдляimgтега -
alt? - строка с описанием изображения -
ref? - ссылка на тегimgизображения -
layout? - enum, абстракция над поведением изображения, как у Next.js -
sizes? - html атрибутsizes, подсказывает браузеру, на каких размерах экрана какое пространство займет изоборажение. Дляresponsiveиfillпо дефолту100vw, для прочих отсутствует. -
deviceSizes? - для responsive макета, то что пойдет вsrcSet? -
quality? -lowилиhigh, качество сжатия, вimgproxyпресеты передаетсяcompressedиcompressed95соответственно -
enlarge? - boolean, еслиtrue, запрещаем делать ширину изображения больше оригинали, вimgproxyпресеты передаетсяenlarge_off -
priority? - enum, ставимloading="lazy"для низкого приоритета. Потенциальныйpreloadдля высокого. -
decoding? - enum, стандартный атрибутdecodingдляimgтега -
style? - строка, стандартный атрибутstyleдля HTML тега -
objectFit? - строка, css свойствоobject-fitдляimgтега -
objectPosition? - строка, css свойствоobject-positionдляimgтега -
loader? - функция что бы переопределить логику получения урла изображения -
placeholder? - @todo: абстракция для плейсхолдера с помощью background-image и base64 изображения ??? -
event handlers...
- Изображение растягивается до своей максимальной ширины и высоты
- При этом, изображение не превышает размер контейнера
srcsetсодержит размеры на 1x и 2x
- Изображение имеет фиксированную ширину и высоту
srcsetсодержит размеры на 1x и 2x
- Изображение растягивается до ширины контейнера
srcsetсодержит размеры изdeviceSizes
- Изображение растягивается до ширины и высоты контейнера
- Дефолтный
object-fit-cover srcsetсодержит размеры изdeviceSizes
-
Хотим просто сжать изображение на лету, и отдать его в современном формате по возможности
Использование:
import { Image } from '@tramvai/image'; import testImg from './images/test.jpg'; const Component = () => { return <Image src={testImg} />; };
Результат:
<img src="...retina_x2/url" srcset=" .../url 1x, ...retina_x2/url 2x " style="display: block; max-width: 100%; height: auto" />
-
Хотим дополнительно указать, что на экранах шире 400px изображение занимает только половину экрана
Использование:
import { Image } from '@tramvai/image'; import testImg from './images/test.jpg'; const Component = () => { return <Image src={testImg} sizes=" (max-width: 400px) 100vw, 50vw " />; };
Результат:
<img src="...retina_x2/url" srcset=" .../url 1x, ...retina_x2/url 2x " sizes=" (max-width: 400px) 100vw 50vw " style="display: block; max-width: 100%; height: auto" />
-
Хотим сделать адаптивное изображение, растягивающееся по всей ширине контейнера
Использование:
import { Image } from '@tramvai/image'; import testImg from './images/test.jpg'; const Component = () => { return <Image src={testImg} layout="responsive" />; };
Результат:
<img src="...1920_x2/url" srcset=" ...360_x2/url 720w, ...414_x2/url 828w, ...1366/url 1366w, ...1920/url 1920w, ...1920_x2/url 3840w " sizes="100vw" style="display: block; width: 100%; height: auto" />
-
Хотим сделать изображение, заполняющее контейнер по ширине и высоте
Использование:
import { Image } from '@tramvai/image'; import testImg from './images/test.jpg'; const Component = () => { return <Image src={testImg} layout="fill" />; };
Результат:
<img src="...1920_x2/url" srcset=" ...360_x2/url 720w, ...414_x2/url 828w, ...1366/url 1366w, ...1920/url 1920w, ...1920_x2/url 3840w " sizes="100vw" style="display: block; width: 100%; height: 100%; object-fit: cover" />
-
@todo: Хотим добавить плейсхолдер
IMGPROXY_URL- путь доimgproxy- Требуется
diпровайдер - Требуется
storeпровайдер? - Требуется
mediaстор?
-
preconnectссылка кIMGPROXY_URL -
preloadссылка на изображение с высоким приоритетом? -
"прогрев" ссылок на изображение в
imgproxy? -
Ширина и высота
При статическом импорте изображения нам нужно знать ширину и высоту изображения. Также, неплохо бы сразу генерировать заблюренный плейсхолдер в base64. Самый простой способ сделать это -
webpackloader типа next-image-loader. Но, нужна обратная совместимость, т.к. импорт вместо строки начнет возвращать объект. Два варианта решения:- Применять этот loader для конфигуриуемой папки, например
src/assets/images - Применять этот loader для файлов с суффиксом типа
.module, напримерimage.module.png
- Применять этот loader для конфигуриуемой папки, например