Начало работы с NgOptimizedImage
Директива NgOptimizedImage упрощает применение лучших практик повышения производительности при загрузке изображений.
Директива обеспечивает приоритетную загрузку изображения наибольшего содержимого (LCP) за счет следующих действий:
- Автоматически задает атрибут
fetchpriorityдля тега<img> - По умолчанию отложенно загружает остальные изображения
- Автоматически добавляет тег preconnect link в заголовок документа
- Автоматически создает атрибут
srcset - Создает подсказку preload, если приложение использует SSR
Помимо оптимизации загрузки изображения LCP, NgOptimizedImage обеспечивает соблюдение ряда рекомендаций по работе с изображениями, например:
- Использование URL-адресов CDN изображений для оптимизации изображений
- Предотвращение сдвигов макета благодаря обязательному указанию
widthиheight - Предупреждение, если
widthилиheightзаданы неправильно - Предупреждение, если при отображении изображение будет визуально искажено
Если вы используете фоновое изображение в CSS, начните отсюда.
ПРИМЕЧАНИЕ: Хотя директива NgOptimizedImage стала стабильной функцией в Angular версии 15, она была перенесена и также доступна как стабильная функция в версиях 13.4.0 и 14.3.0.
Начало работы
-
Импорт директивы NgOptimizedImage
Импортируйте директиву
NgOptimizedImageиз@angular/common:import {NgOptimizedImage} from '@angular/common';и добавьте ее в массив
importsавтономного компонента или NgModule:imports: [ NgOptimizedImage, // ... ],
-
(Необязательно) Настройка загрузчика
Для использования NgOptimizedImage загрузчик изображений не является обязательным, однако его использование с CDN изображений открывает доступ к мощным функциям повышения производительности, включая автоматические
srcsetдля изображений.Краткое руководство по настройке загрузчика приведено в разделе Настройка загрузчика изображений в конце этой страницы.
-
Включение директивы
Чтобы активировать директиву
NgOptimizedImage, замените атрибут изображенияsrcнаngSrc.<img ngSrc="cat.jpg" />
Если вы используете встроенный сторонний загрузчик, не указывайте базовый путь URL в
src, поскольку загрузчик добавит его автоматически. -
Отметка изображений как приоритетных
Всегда отмечайте изображение LCP на странице как
priority, чтобы задать для него приоритет при загрузке.<img ngSrc="cat.jpg" width="400" height="200" priority />
Отметка изображения как
priorityприменяет следующие оптимизации:- Устанавливает
fetchpriority=high(подробнее о подсказках приоритета можно прочитать здесь) - Устанавливает
loading=eager(подробнее о встроенной отложенной загрузке можно прочитать здесь) - Автоматически создает элемент preload link при рендеринге на сервере.
Во время разработки Angular выдает предупреждение, если элемент LCP является изображением без атрибута
priority. Элемент LCP страницы может меняться в зависимости от ряда факторов, например от размера экрана пользователя, поэтому несколько изображений на странице могут требовать отметкиpriority. Подробнее см. в статье CSS для Web Vitals. - Устанавливает
-
Указание ширины и высоты
Чтобы предотвратить сдвиги макета, вызванные изображениями, NgOptimizedImage требует указать высоту и ширину изображения, например:
<img ngSrc="cat.jpg" width="400" height="200" />
Для адаптивных изображений (изображений, размер которых вы настроили так, чтобы он изменялся относительно области просмотра) атрибуты
widthиheightдолжны содержать исходные размеры файла изображения. Для адаптивных изображений также важно задать значение дляsizes.Для изображений фиксированного размера атрибуты
widthиheightдолжны соответствовать желаемому размеру отображаемого изображения. Соотношение сторон этих атрибутов всегда должно совпадать с исходным соотношением сторон изображения.ПРИМЕЧАНИЕ: Если размер изображений неизвестен, рассмотрите возможность использования «режима заполнения», который наследует размер родительского контейнера, как описано ниже.
Использование режима заполнения
Если нужно, чтобы изображение заполняло содержащий его элемент, можно использовать атрибут fill. Это часто полезно, когда требуется добиться поведения «фонового изображения». Этот режим также может пригодиться, если точные ширина и высота изображения неизвестны, но имеется родительский контейнер известного размера, в который нужно вписать изображение (см. раздел «object-fit» ниже).
При добавлении к изображению атрибута fill не нужно и не следует указывать width и height, как в этом примере:
<img ngSrc="cat.jpg" fill />
С помощью CSS-свойства object-fit можно изменить способ заполнения контейнера изображением. Если задать изображению стиль object-fit: "contain", оно сохранит соотношение сторон и будет вписано в элемент с полосами по краям. Если задать object-fit: "cover", элемент сохранит соотношение сторон и полностью заполнит контейнер, при этом часть содержимого может быть обрезана.
Визуальные примеры приведены в документации MDN по object-fit.
Также можно задать изображению стиль с помощью свойства object-position, чтобы настроить его положение внутри содержащего элемента.
ВАЖНО: Чтобы изображение в режиме «fill» отображалось правильно, для его родительского элемента необходимо задать стиль position: "relative", position: "fixed" или position: "absolute".
Перенос фонового изображения
Ниже приведена простая пошаговая инструкция по переходу с background-image на NgOptimizedImage. Далее элемент с фоновым изображением будем называть «содержащим элементом»:
- Удалите стиль
background-imageу содержащего элемента. - Убедитесь, что для содержащего элемента задано
position: "relative",position: "fixed"илиposition: "absolute". - Создайте новый элемент изображения внутри содержащего элемента и используйте
ngSrcдля включения директивыNgOptimizedImage. - Задайте для этого элемента атрибут
fill. Не указывайтеheightиwidth. - Если вы считаете, что это изображение может быть элементом LCP, добавьте к элементу изображения атрибут
priority.
Настроить способ заполнения контейнера фоновым изображением можно так, как описано в разделе Использование режима заполнения.
Использование заполнителей
Автоматические заполнители
NgOptimizedImage может автоматически показывать изображение с низким разрешением в качестве заполнителя, если вы используете CDN или хост изображений, поддерживающий автоматическое изменение размера. Чтобы воспользоваться этой функцией, добавьте к изображению атрибут placeholder:
<img ngSrc="cat.jpg" width="400" height="200" placeholder />
Добавление этого атрибута автоматически запрашивает с помощью указанного загрузчика изображений вторую, уменьшенную версию изображения. Пока изображение загружается, эта небольшая версия отображается как стиль background-image с размытием CSS. Если загрузчик изображений не указан, создать изображение-заполнитель не удастся, и будет вызвана ошибка.
Ширина создаваемых заполнителей по умолчанию составляет 30px. Изменить ее можно, указав значение в пикселях в провайдере IMAGE_CONFIG, как показано ниже:
providers: [
{
provide: IMAGE_CONFIG,
useValue: {
placeholderResolution: 40
}
},
],
Чтобы края размытого заполнителя были четкими, можно обернуть изображение в содержащий <div> со стилем overflow: hidden. Если <div> имеет тот же размер, что и изображение (например, благодаря стилю width: fit-content), размытые края заполнителя будут скрыты.
Заполнители с URL данных
Также можно задать заполнитель без загрузчика изображений, используя URL данных в формате base64. Формат URL данных — data:image/[imagetype];[data], где [imagetype] — формат изображения, например png, а [data] — изображение, закодированное в base64. Кодирование можно выполнить из командной строки или на JavaScript. Примеры команд приведены в документации MDN. Ниже приведен пример URL данных для заполнителя с усеченными данными:
<img ngSrc="cat.jpg" width="400" height="200" placeholder="data:image/png;base64,iVBORw0K..." />
Однако большие URL данных увеличивают размер пакетов Angular и замедляют загрузку страницы. Если использовать загрузчик изображений невозможно, команда Angular рекомендует ограничить размер изображений-заполнителей base64 значением менее 4KB и использовать их только для критически важных изображений. Помимо уменьшения размеров заполнителей, рассмотрите возможность изменения форматов изображений или параметров, используемых при их сохранении. При очень низком разрешении эти параметры могут значительно повлиять на размер файла.
Заполнители без размытия
По умолчанию NgOptimizedImage применяет к заполнителям изображений эффект размытия CSS. Чтобы отобразить заполнитель без размытия, передайте аргумент placeholderConfig с объектом, содержащим свойство blur, которому присвоено значение false. Например:
<img ngSrc="cat.jpg" width="400" height="200" placeholder [placeholderConfig]="{blur: false}" /> Настройка стилей изображений
В зависимости от стилей изображения добавление атрибутов width и height может привести к изменению его отображения. NgOptimizedImage предупреждает, если стили изображения приводят к его отображению с искаженным соотношением сторон.
Обычно это можно исправить, добавив к стилям изображения height: auto или width: auto. Подробнее см. в статье web.dev о теге <img>.
Если атрибуты width и height изображения мешают задать нужный размер с помощью CSS, рассмотрите возможность использования режима fill и настройки стилей родительского элемента изображения.
Возможности повышения производительности
NgOptimizedImage включает ряд функций, предназначенных для повышения производительности загрузки в приложении. Они описаны в этом разделе.
Добавление подсказок для ресурсов
Подсказка для ресурса preconnect для источника изображений обеспечивает максимально быструю загрузку изображения LCP.
Ссылки preconnect автоматически создаются для доменов, переданных в качестве аргумента загрузчику. Если источник изображения не удается определить автоматически и для изображения LCP не обнаружена ссылка preconnect, NgOptimizedImage выдаст предупреждение во время разработки. В этом случае следует вручную добавить подсказку для ресурса в index.html. В <head> документа добавьте тег link с атрибутом rel="preconnect", как показано ниже:
<link rel="preconnect" href="https://my.cdn.origin" />
Чтобы отключить предупреждения preconnect, внедрите токен PRECONNECT_CHECK_BLOCKLIST:
providers: [
{provide: PRECONNECT_CHECK_BLOCKLIST, useValue: 'https://your-domain.com'}
],
Подробнее об автоматическом создании preconnect можно узнать здесь.
Запрос изображений нужного размера с помощью автоматического srcset
Указание атрибута srcset гарантирует, что браузер запрашивает изображение подходящего для области просмотра пользователя размера и не тратит время на загрузку слишком большого изображения. NgOptimizedImage создает подходящий srcset для изображения на основе наличия и значения атрибута sizes тега изображения.
Изображения фиксированного размера
Если размер изображения должен быть фиксированным (то есть одинаковым на разных устройствах, за исключением плотности пикселей), задавать атрибут sizes не нужно. srcset можно создать автоматически на основе атрибутов ширины и высоты изображения без дополнительных настроек.
Пример созданного srcset:
<img ... srcset="image-400w.jpg 1x, image-800w.jpg 2x" />
Адаптивные изображения
Если изображение должно быть адаптивным (то есть увеличиваться и уменьшаться в зависимости от размера области просмотра), для создания srcset необходимо задать атрибут sizes.
Если вы раньше не использовали sizes, для начала можно задать его на основе ширины области просмотра. Например, если CSS растягивает изображение на 100% ширины области просмотра, задайте для sizes значение 100vw — тогда браузер выберет изображение из srcset, ширина которого ближе всего к ширине области просмотра (с учетом плотности пикселей). Если изображение, скорее всего, будет занимать только половину экрана (например, в боковой панели), задайте для sizes значение 50vw, чтобы браузер выбрал изображение меньшего размера. И так далее.
Если описанное выше не позволяет добиться нужного поведения изображения, см. документацию по расширенным значениям sizes.
Обратите внимание: NgOptimizedImage автоматически добавляет "auto" в начало указанного значения sizes. Это повышает точность выбора srcset в браузерах с поддержкой sizes="auto" и игнорируется браузерами без такой поддержки.
По умолчанию используются следующие контрольные точки адаптивности:
[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]
Изменить эти контрольные точки можно с помощью провайдера IMAGE_CONFIG:
providers: [
{
provide: IMAGE_CONFIG,
useValue: {
breakpoints: [16, 48, 96, 128, 384, 640, 750, 828, 1080, 1200, 1920]
}
},
],
Если вы хотите вручную задать атрибут srcset, используйте собственное значение атрибута ngSrcset:
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w" />
Если присутствует атрибут ngSrcset, NgOptimizedImage создает и задает srcset на основе указанных размеров. Не добавляйте имена файлов изображений в ngSrcset — директива получает эту информацию из ngSrc. Директива поддерживает дескрипторы ширины (например, 100w) и дескрипторы плотности (например, 1x).
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w" sizes="50vw" />
Отключение автоматического создания srcset
Чтобы отключить создание srcset для одного изображения, добавьте к нему атрибут disableOptimizedSrcset:
<img ngSrc="about.jpg" disableOptimizedSrcset />
Отключение отложенной загрузки изображений
По умолчанию NgOptimizedImage задает loading=lazy для всех изображений, не отмеченных как priority. Это поведение можно отключить для неприоритетных изображений, задав атрибут loading. Этот атрибут принимает значения eager, auto и lazy. Подробнее см. в документации по стандартному атрибуту изображения loading.
<img ngSrc="cat.jpg" width="400" height="200" loading="eager" />
Управление декодированием изображений
По умолчанию NgOptimizedImage задает decoding="auto" для всех изображений. Это позволяет браузеру самостоятельно выбрать оптимальное время декодирования изображения после загрузки. Если изображение отмечено как priority, Angular автоматически задает decoding="sync", чтобы изображение декодировалось и отображалось как можно раньше, повышая производительность наибольшего содержимого (LCP).
Это поведение по-прежнему можно переопределить, явно задав атрибут decoding.
Подробнее см. в документации по стандартному атрибуту изображения decoding.
<!-- Default: decoding is 'auto' --> <img ngSrc="gallery/landscape.jpg" width="1200" height="800" /> <!-- Decode the image asynchronously to avoid blocking the main thread.--> <img ngSrc="gallery/preview.jpg" width="600" height="400" decoding="async" /> <!-- Priority images automatically use decoding="sync" --> <img ngSrc="awesome.jpg" width="500" height="625" priority /> <!-- Decode immediately (can block) when you need the pixels right away --> <img ngSrc="hero.jpg" width="1600" height="900" decoding="sync" />
Допустимые значения
-
auto(по умолчанию): позволяет браузеру выбрать оптимальную стратегию. -
async: декодирует изображение асинхронно, по возможности избегая блокировки основного потока. -
sync: декодирует изображение немедленно; это может заблокировать рендеринг, но пиксели будут готовы сразу после загрузки изображения.
Расширенные значения 'sizes'
Можно настроить отображение изображений разной ширины на экранах разных размеров. Распространенный пример — макет на основе сетки или колонок, в котором на мобильных устройствах отображается одна колонка, а на устройствах с большими экранами — две. Такое поведение можно описать атрибутом sizes с использованием синтаксиса «медиазапросов», например:
<img ngSrc="cat.jpg" width="400" height="200" sizes="(max-width: 768px) 100vw, 50vw" />
Атрибут sizes в примере выше означает: «Я ожидаю, что на устройствах шириной менее 768px это изображение будет занимать 100 процентов ширины экрана. В противном случае я ожидаю, что оно будет занимать 50 процентов ширины экрана».
Дополнительную информацию об атрибуте sizes см. на сайтах web.dev или MDN.
Настройка загрузчика изображений для NgOptimizedImage
«Загрузчик» — это функция, которая создает URL-адрес преобразования изображения для заданного файла изображения. Когда это необходимо, NgOptimizedImage задает преобразования размера, формата и качества изображения.
NgOptimizedImage предоставляет как универсальный загрузчик без преобразований, так и загрузчики для различных сторонних сервисов изображений. Также поддерживается создание собственных загрузчиков.
| Тип загрузчика | Поведение |
|---|---|
| Универсальный загрузчик | URL-адрес, возвращаемый универсальным загрузчиком, всегда совпадает со значением src. Другими словами, этот загрузчик не выполняет преобразований. Основной вариант использования этого загрузчика — сайты, на которых изображения обслуживаются с помощью Angular. |
| Загрузчики для сторонних сервисов изображений | URL-адреса, возвращаемые загрузчиками для сторонних сервисов изображений, соответствуют соглашениям API конкретного сервиса изображений. |
| Пользовательские загрузчики | Поведение пользовательского загрузчика определяется его разработчиком. Пользовательский загрузчик следует использовать, если ваш сервис изображений не поддерживается загрузчиками, предварительно настроенными в NgOptimizedImage. |
Учитывая распространенность различных сервисов изображений в приложениях Angular, NgOptimizedImage предоставляет предварительно настроенные загрузчики для следующих сервисов:
| Сервис изображений | API Angular | Документация |
|---|---|---|
| Cloudflare Image Resizing | provideCloudflareLoader | Документация |
| Cloudinary | provideCloudinaryLoader | Документация |
| ImageKit | provideImageKitLoader | Документация |
| Imgix | provideImgixLoader | Документация |
| Netlify | provideNetlifyLoader | Документация |
Для использования универсального загрузчика не требуется вносить дополнительные изменения в код. Это поведение используется по умолчанию.
Встроенные загрузчики
Чтобы использовать существующий загрузчик для стороннего сервиса изображений, добавьте фабрику провайдера выбранного сервиса в массив providers. В примере ниже используется загрузчик Imgix:
providers: [
provideImgixLoader('https://my.base.url/'),
],
Базовый URL ресурсов изображений следует передать в фабрику провайдера в качестве аргумента. Для большинства сайтов этот базовый URL должен соответствовать одному из следующих шаблонов:
Подробнее о структуре базового URL можно узнать в документации соответствующего провайдера CDN.
Пользовательские загрузчики
Чтобы использовать пользовательский загрузчик, передайте функцию загрузчика в качестве значения DI-токена IMAGE_LOADER. В приведенном ниже примере функция пользовательского загрузчика возвращает URL, начинающийся с https://example.com и содержащий src, width и height в качестве параметров URL.
providers: [
{
provide: IMAGE_LOADER,
useValue: (config: ImageLoaderConfig) => {
return `https://example.com/images?src=${config.src}&width=${config.width}&height=${config.height}`;
},
},
],
Функция загрузчика для директивы NgOptimizedImage принимает в качестве аргумента объект типа ImageLoaderConfig (из @angular/common) и возвращает абсолютный URL ресурса изображения. Объект ImageLoaderConfig содержит свойство src, а также необязательные свойства width, height и loaderParams.
ПРИМЕЧАНИЕ: хотя свойство width может присутствовать не всегда, пользовательский загрузчик должен использовать его для поддержки запросов изображений разной ширины, чтобы ngSrcset работал правильно.
Свойство loaderParams
Директива NgOptimizedImage поддерживает дополнительный атрибут loaderParams, специально предназначенный для работы с пользовательскими загрузчиками. Атрибут loaderParams принимает в качестве значения объект с произвольными свойствами и сам по себе ничего не делает. Данные из loaderParams добавляются в объект ImageLoaderConfig, передаваемый пользовательскому загрузчику, и могут использоваться для управления его поведением.
Часто loaderParams используется для управления расширенными функциями CDN изображений.
Использование свойства transform со встроенными загрузчиками
Встроенные загрузчики для Cloudinary, Cloudflare, ImageKit и Imgix поддерживают специальное свойство transform в loaderParams. Это свойство позволяет применять пользовательские преобразования изображений, предоставляемые вашей CDN.
Свойство transform принимает два формата:
Строковый формат
Укажите преобразования в виде строки, разделенной запятыми, используя синтаксис преобразований вашей CDN:
<img
ngSrc="my-image.jpg"
width="400"
height="300"
[loaderParams]="{transform: 'e_grayscale,r_10'}"
/> Формат объекта
Укажите преобразования в виде объекта с парами «ключ — значение».
<img
ngSrc="my-image.jpg"
width="400"
height="300"
[loaderParams]="{transform: {e: 'grayscale', r: 10}}"
/>
ПРИМЕЧАНИЕ: свойство transform не поддерживается загрузчиком Netlify, поскольку CDN изображений Netlify не предоставляет пользовательские параметры преобразования.
Пример пользовательского загрузчика
Ниже показан пример функции пользовательского загрузчика. Эта функция объединяет src, width и height, а также использует loaderParams для управления пользовательской функцией CDN, добавляющей скругленные углы:
const myCustomLoader = (config: ImageLoaderConfig) => {
let url = `https://example.com/images/${config.src}?`;
let queryParams = [];
if (config.width) {
queryParams.push(`w=${config.width}`);
}
if (config.height) {
queryParams.push(`h=${config.height}`);
}
if (config.loaderParams?.roundedCorners) {
queryParams.push('mask=corners&corner-radius=5');
}
return url + queryParams.join('&');
};
Обратите внимание: в примере выше мы придумали имя свойства 'roundedCorners' для управления функцией пользовательского загрузчика. Затем эту функцию можно использовать при создании изображения, как показано ниже:
<img ngSrc="profile.jpg" width="300" height="300" [loaderParams]="{roundedCorners: true}" /> Часто задаваемые вопросы
Поддерживает ли NgOptimizedImage свойство CSS background-image?
NgOptimizedImage напрямую не поддерживает свойство CSS background-image, но позволяет легко реализовать сценарий, в котором изображение используется в качестве фона другого элемента.
Пошаговую инструкцию по переходу с background-image на NgOptimizedImage см. в расположенном выше разделе Перенос фонового изображения.
Почему нельзя использовать src с NgOptimizedImage?
Атрибут ngSrc был выбран в качестве триггера для NgOptimizedImage с учетом технических особенностей загрузки изображений браузером. NgOptimizedImage программно изменяет атрибут loading. Если браузер увидит атрибут src до внесения этих изменений, он начнет немедленно скачивать файл изображения, а изменения параметров загрузки будут проигнорированы.
Почему для домена моих изображений не создается элемент preconnect?
Элементы preconnect создаются на основе статического анализа приложения. Это значит, что домен изображений должен быть непосредственно указан в параметре загрузчика, как в следующем примере:
providers: [
provideImgixLoader('https://my.base.url/'),
],
Если для передачи строки домена в загрузчик используется переменная или загрузчик не используется, статический анализ не сможет определить домен, и ссылка preconnect не будет создана. В этом случае следует вручную добавить ссылку preconnect в заголовок документа, как описано выше.
Можно ли использовать на одной странице два разных домена изображений?
Шаблон поставщика загрузчиков изображений разработан так, чтобы быть максимально простым для распространённого сценария, когда в компоненте используется только один CDN изображений. Однако вполне возможно управлять несколькими CDN изображений с помощью одного поставщика.
Для этого мы рекомендуем написать пользовательский загрузчик изображений, который использует свойство loaderParams для передачи флага, указывающего, какой CDN изображений следует использовать, а затем вызывает соответствующий загрузчик на основе этого флага.
Можете ли вы добавить встроенный загрузчик для предпочитаемого мной CDN?
По причинам, связанным с сопровождением, мы пока не планируем добавлять поддержку дополнительных встроенных загрузчиков в репозиторий Angular. Вместо этого мы рекомендуем разработчикам публиковать дополнительные загрузчики изображений в виде сторонних пакетов.
Можно ли использовать это с тегом <picture>
Нет, но эта возможность есть в нашей дорожной карте, следите за обновлениями.
Если вы ждёте эту функцию, проголосуйте за соответствующую проблему на GitHub здесь.
Как найти изображение LCP с помощью Chrome DevTools?
-
На вкладке производительности Chrome DevTools нажмите кнопку «Начать запись профиля и перезагрузить страницу» в левом верхнем углу. Она выглядит как значок обновления страницы.
-
Это запустит запись профиля вашего приложения Angular.
-
Когда результат записи профиля будет готов, выберите «LCP» в разделе с временными показателями.
-
В нижней части панели должна появиться сводная запись. Элемент LCP можно найти в строке «связанный узел». Нажмите на неё, чтобы увидеть этот элемент на панели Elements.
ПРИМЕЧАНИЕ: Так можно определить только элемент LCP в области просмотра тестируемой страницы. Также рекомендуется использовать эмуляцию мобильного устройства, чтобы определить элемент LCP для экранов меньшего размера.
Super-powered by Google ©2010–2025.
Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0.
https://angular.dev/guide/image-optimization