---
layout: post
title: Адаптивная загрузка изображений
authors:
  - katiehempenius
description: При загрузке на мобильных устройствах изображений, предназначенных для ПК, расход трафика может быть в 2–4 раза выше, чем нужно. Вместо того чтобы использовать универсальные изображения, размер изображений можно выбирать исходя из формата устройства.
date: 2018-11-05
updated: 2021-06-04
codelabs:
  - codelab-specifying-multiple-slot-widths
  - codelab-art-direction
  - codelab-density-descriptors
tags:
  - performance
---

При загрузке на мобильных устройствах изображений, предназначенных для ПК, расход трафика может быть в 2–4 раза выше, чем нужно. Вместо того чтобы использовать универсальные изображения, размер изображений можно выбирать исходя из формата устройства.

## Изменение размера изображений

Одни из наиболее популярных инструментов для изменения размера изображений — это [npm-пакет sharp](https://www.npmjs.com/package/sharp) и [инструмент ImageMagick для командной строки](https://www.imagemagick.org/script/index.php).

Пакет sharp — хороший выбор для автоматизации изменения размера изображений (например, при создании для всех видео на вашем сайте миниатюр различных размеров). Он быстро работает и с легкостью интегрируется со скриптами и инструментами сборки. ImageMagick, напротив, удобен для разового изменения размера изображений, так как используется исключительно через командную строку.

### sharp

Чтобы использовать sharp в качестве Node-скрипта, сохраните приведенный ниже код как отдельный скрипт в вашем проекте, а затем запустите его для преобразования ваших изображений:

```javascript
const sharp = require('sharp');
const fs = require('fs');
const directory = './images';

fs.readdirSync(directory).forEach(file => {
  sharp(`${directory}/${file}`)
    .resize(200, 100) // width, height
    .toFile(`${directory}/${file}-small.jpg`);
  });
```

### ImageMagick

Чтобы изменить размер изображения до 33% от его исходного размера, выполните в терминале следующую команду:

```bash
convert -resize 33% flower.jpg flower-small.jpg
```

Чтобы изменить размер изображения до не более чем 300 пикселей в ширину и 200 пикселей в высоту, выполните следующую команду:

```bash
# macOS/Linux
convert flower.jpg -resize 300x200 flower-small.jpg

# Windows
magick convert flower.jpg -resize 300x200 flower-small.jpg
```

### Сколько версий изображений нужно создавать?

На этот вопрос нет однозначного «правильного» ответа, однако обычно используются 3–5 разных вариантов изображения. Выдача изображений различных размеров позволяет повысить производительность, но увеличивает расход места на серверах и требует написания дополнительного HTML-кода.

### Другие варианты

Вы также можете попробовать воспользоваться сервисами обработки изображений, такими как [Thumbor](https://github.com/thumbor/thumbor) (с открытым исходным кодом) и [Cloudinary](https://cloudinary.com/). Сервисы обработки изображений позволяют по требованию генерировать адаптивные изображения (и производить манипуляции с изображениями). Thumbor устанавливается на сервер, тогда как для Cloudinary настройка сервера не требуется. Оба этих решения являются простыми способами создания адаптивных изображений.

## Загрузка различных вариантов изображений

Укажите несколько вариантов изображения, и браузер выберет наиболее подходящую:

<div class="table-wrapper scrollbar">
  <table>
    <thead>
      <tr>
        <th><strong>Было</strong></th>
        <th><strong>Стало</strong></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          &lt;img src="flower-large.jpg"&gt;
        </td>
        <td>
          &lt;img src="flower-large.jpg" srcset="flower-small.jpg 480w,
          flower-large.jpg 1080w" sizes="50vw"&gt;
        </td>
      </tr>
    </tbody>
  </table>
</div>

Для достижения конечного результата используется комбинация атрибутов [`src`](https://developer.mozilla.org/docs/Web/HTML/Element/img#attr-src), [`srcset`](https://developer.mozilla.org/docs/Web/HTML/Element/img#attr-srcset) и [`sizes`](https://developer.mozilla.org/docs/Web/HTML/Element/img#attr-sizes) элемента `<img>`.

### Атрибут «src»

Атрибут src позволяет коду работать в браузерах, которые [не поддерживают](https://caniuse.com/#search=srcset) `srcset` и `sizes`. Если браузер не поддерживает эти атрибуты, то загружается ресурс, указанный в атрибуте `src`.

{% Aside 'gotchas' %} Ресурс, указанный в атрибуте `src`, должен быть достаточно большим, чтобы подходить для устройств любого размера. {% endAside %}

### Атрибут «srcset»

Атрибут `srcset` принимает разделенный запятыми список изображений с указанием имен файлов и дескрипторов ширины или плотности пикселей.

В этом примере используются [дескрипторы ширины](https://www.w3.org/TR/html5/semantics-embedded-content.html#width-descriptor). `480w` — это дескриптор ширины, сообщающий браузеру, что `flower-small.jpg` имеет ширину 480 пикселей; `1080w` — это дескриптор ширины, сообщающий браузеру, что `flower-large.jpg` имеет ширину 1080 пикселей.

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

{% Aside 'gotchas' %} Для указания дескрипторов ширины используйте окончание `w` (вместо `px`). Например, для изображения шириной 1024 пикселя следует указать дескриптор `1024w`. {% endAside %}

**Дополнительная информация:** для показа изображений различных размеров вам не нужно ничего знать о дескрипторах плотности пикселей. Но если вам интересно, как они работают, ознакомьтесь с [проектом «Переключение разрешения» в Codelabs](/codelab-density-descriptors). Дескрипторы плотности пикселей используются для выбора изображений с учетом [плотности пикселей](https://en.wikipedia.org/wiki/Pixel_density) устройства.

### Атрибут «sizes»

Атрибут sizes сообщает браузеру, какую изображение будет иметь ширину при отображении. Однако атрибут sizes никак не учитывает размер экрана; для этого по-прежнему понадобится CSS.

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

Если браузер не распознает атрибут «`sizes`», то будет загружено изображение, указанное в атрибуте «`src`». (Поддержка атрибутов «`sizes`» и «`srcset`» появилась в браузерах одновременно, поэтому браузер будет поддерживать либо оба атрибута, либо ни тот, ни другой.)

{% Aside 'gotchas' %} Ширина области отображения может указываться в различных единицах. Все примеры ниже являются допустимыми:

- `100px`
- `33vw`
- `20em`
- `calc(50vw-10px)`

Следующий размер не является допустимым:

- `25%` (в атрибуте sizes нельзя использовать проценты) {% endAside %}

**Дополнительная информация:** если вы хотите проявить изобретательность, вы также можете указать при помощи атрибута sizes несколько размеров областей отображения. Эту возможность можно использовать на сайтах, макет выбирается в зависимости от размера области просмотра. Чтобы узнать, как это сделать, ознакомьтесь с [примером кода, использующего множественные области отображения](/codelab-specifying-multiple-slot-widths).

### Информация для дальнейшего изучения

Помимо дополнительной информации, приведенной выше (изображения — сложная тема!), вы также можете использовать концепции, описанные в этой статье, для [художественного преобразования](https://developer.mozilla.org/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Art_direction). Художественное преобразование — это когда в зависимости от размера области просмотра происходит загрузка совершенно разных изображений (а не разных версий одного изображения). Подробности вы можете узнать, ознакомившись с [проектом «Художественное преобразование» в Codelabs](/codelab-art-direction).

## Проверка

После внедрения адаптивных изображений вы можете воспользоваться Lighthouse, чтобы убедиться, что ни одно изображение не было пропущено. Запустите в Lighthouse проверку производительности (**Lighthouse &gt; Options &gt; Performance**) и посмотрите результаты проверки **Properly size images** («Корректное масштабирование изображений»). Там вы увидите список изображений, которые требуют масштабирования.
