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

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

Адаптивные изображения

Qwik поддерживает адаптивные изображения.

Это встроенная функция, основанная на модуле vite-imagetools, поэтому не требуется устанавливать дополнительные пакеты или компоненты.

Как это работает

  • Импортируйте любое изображение из папки src.
  • Изображение преобразуется в несколько webp-изображений, по одному для каждого брейкпойнта (200px, 400px, 600px, 800px, 1200px).
  • Изображение обработано и оптимизировано для уменьшения его размера.
  • Элемент <img> визуализируется с использованием атрибута srcset для установки источника изображения для нескольких разрешений.
  • Теперь браузер будет загружать изображение, наиболее подходящее для используемого разрешения.

Ключевые моменты

Сообществу и команде Qwik нравится этот API по ряду причин:

  • Отсутствие рантайма и JS.
  • Не требует настройки по умолчанию, простой API.
  • Отсутствие страницы 404, строго типизированный API.
  • Отсутствие перекомпоновки макета (автоматическая установка ширины и высоты).
  • Хешированные изображения, неизменяемый кэш.
  • Автоматическая оптимизация форматов .webp / .avif.
  • Автоматизированное формирование srcSet.
  • Расширяемость (использование любого атрибута <img>).
  • Ленивая загрузка и асинхронное декодирование по умолчанию.
  • Легковесный, единственный узел <img> в HTML.

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

Добавьте суффикс ?jsx в конце импорта.

import Image from '[IMAGE_PATH]?jsx';

Используйте изображение в шаблоне в качестве компонента:

<Image />

Результат

Этот скрипт сгенерирует следующий элемент <img>:

<img
  decoding="async"
  loading="lazy"
  srcset="
    /@imagetools/141464b77ebd76570693f2e1a6b0364f4b4feea7 200w,
    /@imagetools/e70ec011d10add2ba28f9c6973b7dc0f11894307 400w,
    /@imagetools/1f0dd65f511ffd34415a391bf350e7934ce496a1 600w,
    /@imagetools/493154354e7e89c3f639c751e934d1be4fc05827 800w,
    /@imagetools/324867f8f1af03474a17a9d19035e28a4c241aa1 1200w"
  width="1200"
  height="1200"
>
  • decoding="async": указывает на то, что изображение, в процессе его декодирования, не будет блокировать рендер страницы. Дополнительную информацию можно найти в MDN web docs;
  • loading="lazy": позволяет браузеру откладывать загрузку изображения до тех пор, пока оно не будет видно в области просмотра, что помогает улучшить производительность загрузки страницы;
  • srcset: данный атрибут позволяет выбрать наиболее подходящее изображение в зависимости от размера и разрешения экрана устройства;
  • width и height: установка атрибутов width и height предотвращает размытие макета, что снижает эффективность CLS

Примечание: Вы также можете изменить поведение по умолчанию, задав значение этих свойств вручную:

  • <Image decoding="sync" loading="eager" />

Благодаря атрибуту srcset браузер загрузит наиболее подходящее для разрешения устройства изображение:

Первоначальный размер исходного изображения составлял 1,5МБ, но теперь его размер составляет всего несколько килобайт.

Пример

import { component$ } from '@builder.io/qwik';
import Image from '~/media/your_image.png?jsx';
 
export default component$(() => {
  return (
    <div>
      <Image />
    </div>
  );
});

Настройка ширины и высоты изображения

Возможно, вам понадобится установить для изображения конкретную ширину:

<Image style={{ width: '300px'}} />

но в этом случае вам также необходимо вручную указать высоту, чтобы избежать его растягивания:

<Image style={{ width: '300px', height: '200px'}} />

Ниже показан простой приём, позволяющий избежать необходимости вручную устанавливать height, сохраняя при этом соотношение сторон:

Совет: необходимо всегда указывать значения width и height для предотвращения перекомпоновки макета

import { component$ } from '@builder.io/qwik';
import Image from '~/media/emote.png?jsx';
 
export default component$(() => {
  return (
    <>
      <h1>Пример изображения</h1>
      <div class="image-wrapper" >
        <Image />
      </div>
    </>
  );
});
.image-wrapper {
  width: 300px; /* Установите желаемую ширину элемента-обёртки */
  position: relative; /* Требуется для абсолютного позиционирования */
}
 
.image-wrapper img {
  width: 100%; /* Заставьте изображение заполнить ширину контейнера */
  height: auto; /* Позвольте браузеру вычислить высоту, чтобы сохранить соотношение сторон */
  display: block; /* Удалите всё лишнее пространство под изображением */
}

@unpic/qwik

  • Сайт с подробными инструкциями по использованию: @unpic/qwik
  • Установка: npm install @unpic/qwik

Unpic - это сторонняя библиотека оптимизации изображений, которая работает с существующими CDN оптимизации изображений. Она предоставляет компонент Image, который можно использовать для оптимизации изображений.

import { component$ } from '@builder.io/qwik';
import { Image } from '@unpic/qwik';
 
export default component$(() => {
  return (
    <Image
      src="https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg"
      layout="constrained"
      width={800}
      height={600}
      alt="A lovely bath"
    />
  );
});

Примечание: Unpic - не CDN, и не размещает ваши изображения. Он работает с существующими CDN для оптимизации изображений. Мы предлагаем использовать следующие популярные CDN:

  • Cloudinary
  • Cloudflare
  • Bunny.net
  • Vercel / Next.js
  • Imgix, включая Unsplash, DatoCMS, Sanity и Prismic
  • Shopify
  • Kontent.ai
  • Builder.io
  • Contentful
  • Storyblok
  • WordPress.com и Jetpack Site Accelerator

qwik-image

Высококачественные изображения с автоматической оптимизацией.

npm install qwik-image
или
yarn install qwik-image
или
pnpm install qwik-image

Это подключаемый компонент, поэтому разработчики могут подключать к нему различные загрузчики изображений (например, builder.io или другие CDN).

import { $, component$ } from '@builder.io/qwik';
import { Image, useImageProvider } from 'qwik-image';
import {
  Image,
  type ImageTransformerProps,
  useImageProvider,
} from 'qwik-image';
 
export default component$(() => {
  const imageTransformer$ = $(
    ({ src, width, height }: ImageTransformerProps): string => {
      // Здесь вы можете установить ваш любимый сервис загрузчика изображений
      return `https://cdn.builder.io/api/v1/${src}?height=${height}&width=${width}&format=webp&fit=fill`;
    }
  );
 
  // Глобальный провайдер (обязательно)
  useImageProvider({
    // Вы можете установить этот параметр, чтобы перезаписать значения по умолчанию [3840, 1920, 1280, 960, 640].
    resolutions: [640],
    imageTransformer$,
  });
 
  return (
    <Image
      layout="constrained"
      objectFit="fill"
      width={400}
      height={500}
      alt="Tropical paradise"
      placeholder="#e6e6e6"
      src={
        'image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fe5113e1c02db40e5bac75146fa46386f'
      }
    />
  );
});

Здесь находится репозиторий Github с подробными инструкциями по использованию и настройке: qwikifiers/qwik-image.

Участники

Спасибо всем участникам, которые помогли сделать эту документацию лучше!

  • mhevery
  • gioboa
  • fabiobiondi
  • adamdbradley
  • igorbabko
  • Benny-Nottonson
  • mrhoodz
  • avanderpluijm
  • fabian-hiller
  • manucorporat
  • aendel