Skip to content

Latest commit

 

History

History
145 lines (80 loc) · 12.1 KB

12. Работа с изображениями.md

File metadata and controls

145 lines (80 loc) · 12.1 KB

Работа с изображениями

Растр и вектор, JPG и PNG, адаптивность, оптимизации, облачные хранилища, CDN — работа с изображениями это нелёгкая тема

Работа с изображениями в вёрстке это та ещё задача: выбрать правильный формат — jpg/png/svg/webp и др;, подумать об адаптивности — зачем на мобайле грузить большие изображения с десктопа; заморочиться с размерами — не все изображения будут одинаковой ширины и высоты. Ух! Давайте разбираться.

Растр и вектор

Первое, чем отличаются изображения — форматом. Одни растровые, другие векторные.

Растровые

Изображение состоит из сетки пикселей. Растровые изображения плохо масштабируются, потому что по сути вы увеличиваете размер пикселя.

Векторные

Векторные изображения построены из геометрических фигур: точек, квадратов, кругов, кривых, векторов. Масштабируются отлично: потому что геометрия.

Форматы

По форматам легко: в JPG или PNG хранят фотографии и другой контент, а в SVG — иконки.

Ещё у PNG есть прозрачность, а у JPG — качество сжатия: можно понизить "вес" файла просто поставив качество в 80% вместо 100%, особой разницы вы не заметите.

Оптимизация

В изображениях хранятся мета-данные — данные, которые в Вебе нам не особо нужны: фотоаппарат, используемый софт для обработки и другие. Обычно они хранятся в EXIF. Все эти данные можно вырезать — это первый путь оптимизации.

Второй: пожать само изображение (как в случае с процентным качеством JPG). Вручную это делать утомительно, поэтому есть tinypng.com — сервис, который сожмёт изображения.

Но руками каждое изображение жать не очень удобно, поэтому есть много готовых библиотек. Одна из самых популярных ImageMagick, её используют на серверах: человек залил изображение, оно прошло через ImageMagick и указанные настройки, затем сохранилось куда-то.

Хранение изображений

Куда-то? Это куда? В проекте (мы же говорим про фронтэнд) можно хранить только иконки, а контентные изображения (например, фотографии меню, блюд или ресторанов) хранятся в облачных хранилищах и за них отвечает бэкэнд и база данных.

Какие бывают облачные хранилища? Обычно используют Amazon AWS S3 либо аналоги от Гугла (Google Cloud Storage), Майкрософта (Azure Blob Storage), DigitalOcean (Digital Ocean Spaces) и других. Ещё есть Uploadcare — законченное решение вместе с виджетом и хранением.

CDN — распространение изображений

Кстати, хранение изображений это одно, а ведь нужно ещё отвечать за распространение! Этим занимается CDN — Content Delivery Network.

В самом примитивном варианте CDN раздаёт изображения с ближайшего до пользователя сервера: если вы в Европе, то явно вам нужно отдавать данные не из Японии, Франкфурт больше подойдёт.

Как это работает? Банальным дублированием файлом на каждый сервер в каждом регионе — поэтому нужно обычно ждать несколько часов пока изображения появятся на всех CDN-точках провайдера.

Как всегда, есть решения от Amazon (Amazon AWS Cloudfront), Google (Google Cloud CDN) и других.


Зачем мне об этом знать? За это же отвечает бэкэнд?

Вам нужно об этом знать — вы отвечаете за сайт. Если фронтэндер не будет обращать внимания на вес изображений, на скорость загрузки и другие вещи — сайт будет работать медленно. Интерфейс будет работать медленно, бизнес будет терять деньги.

Поэтому в ваших и только в ваших интересах форсить нарезку изображений (когда одно изображение режется несколько раз — для мобайла, планшета и десктопа), их сжатие, использование CDN и другие оптимизации.


Продолжим.

Нарезка под разные разрешения

Я упомянул, что изображения режутся под разные разрешения, а как понять как резать?

В своей практике я видел много подходов, но остановился на одном идеальном: уменьшать по высоте, а за высоту взять степень двойки.

Ограничение по высоте

Чего? Почему по высоте? Потому что зачастую изображения на странице ограничены по высоте, но не по ширине: если вы поставите всем изображениям 256 пикселей ширины, то у одних высота будет в 452 пикселя, у других 211, у третьих 987.

Представьте такую ситуацию на сайте ЦУМ-а? Невозможно.

Или вот ещё пример: фотографии домов. Они могут быть 16:9, могут быть 4:3, могут 3:4, могут 16:10, но при подходе ограничения высоты это не играет никакой роли.

Степень двойки

А что за степень двойки? Это просто самый удобный формат, который легко запоминается: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 и выше.

При таком подходе и ретина-изображения встают идеально: если вам для ретины нужна картинка в 256 пикселей, то берёте 512. Удобно!

Использование в вёрстке

Есть два подхода: либо background-image, либо тег <img>. Разница в их индексируемости поисковиками.

<img>

Индексируются, особенно если прописывать alt="" — описание изображения. Поисковики вас полюбят.

background-image

Не индексируются.

Иконки

Гугл рекомендует использовать svg и вставлять их либо через тег <img>, либо сразу в код; но второй подход неудобен, потому что представьте что вам нужно пройтись по всему проекту, чтобы заменить одну иконку?

Размеры изображения

Если изображение находится в сетке, то обычно им задают ширину в 100% чтобы они растягивались. → Пример.

Если изображение на фоне или само по себе, то задают высоту, чтобы на всё остальное пространство оно растягивалось.

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

Адаптивные изображения, плюс Ретина

Раньше с адаптивностью была дичь — её вообще не было. Сейчас у нас есть тег picture, его поддержка сейчас — 88.22%.

Один из его жирных плюсов — обратная совместимость: даже если браузер не поддерживает тег picture, то изображение всё равно будет у пользователя за счёт тега img.

Пример использования:

<picture>
  <source media="(max-width: 767px)" srcset="https://via.placeholder.com/100x100/E61E7F/ffffff, https://via.placeholder.com/100x100/44BB51/ffffff 2x">
  <source media="(min-width: 768px)" srcset="https://via.placeholder.com/768x100/E61E7F/ffffff, https://via.placeholder.com/768x100/44BB51/ffffff 2x">
  <img src="https://via.placeholder.com/768x100/E61E7F/ffffff" srcset="https://via.placeholder.com/768x100/E61E7F/ffffff 2x" alt="a head carved out of wood">
</picture>

iframe: https://jsfiddle.net/774s3y62/embedded/result/

Если у вас Ретина, то изображение будет зеленым, а если нет — розовым.

Итог

Если фронтэндер не позаботится об изображениях, о них никто не позаботится.

  • использовать JPG когда на изображении нет текста или прозрачности, плюс он дешевле в весе;
  • использовать PNG когда есть текст или прозрачность, придется пожертвовать весом;
  • использовать SVG для иконок;
  • использовать тег <picture> и атрибуты srcset уже можно;
  • оптимизировать через ImageMagick;
  • им же и нарезать по высоте, взяв степень двойки за основу;
  • хранить изображения в облачных сервисах;
  • использовать CDN чтобы пользователь получал изображение с ближайшего сервера.