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

В Vite изображения рассматриваются как часть графа модулей, что позволяет обрабатывать их так же предсказуемо, как JavaScript или CSS. При импорте графических ресурсов система сборки решает, инлайнить файл, перенести его в выходной каталог, переименовать с хэшем или применить трансформации через плагины.

Базовая модель работы строится вокруг двух ключевых механизмов: обработка статических ассетов через import и управление публичными ресурсами через директорию public.

Импорт изображений как модулей

При использовании импорта изображений Vite преобразует их в URL:

import logo from './assets/logo.png'

const img = document.createElement('img')
img.src = logo
document.body.appendChild(img)

На этапе сборки файл logo.png копируется в выходной каталог dist/assets с добавлением хэша:

logo.8f3a91c2.png

Хэширование обеспечивает кеш-бастинг без ручного контроля версий файлов.

Дополнительно поддерживается синтаксис URL-объектов:

const url = new URL('./assets/logo.png', import.meta.url).href

Этот подход особенно полезен при динамическом построении путей и работе в окружениях, где важна совместимость с нативными механизмами браузера.

Разделение public и assets

Vite использует два принципиально разных подхода к изображениям:

  • src/assets — обрабатываемые ресурсы
  • public — статические файлы без трансформации

Файлы из public копируются в корень сборки без изменений:

public/image.png → dist/image.png

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

<img src="/image.png">

Такой подход исключает оптимизацию, но обеспечивает предсказуемый путь и подходит для:

  • favicon
  • robots.txt
  • статических изображений, не участвующих в сборке

При этом изображения в src/assets проходят через пайплайн оптимизации, могут быть инлайнены и участвуют в tree-shaking графа зависимостей.

Инлайнинг изображений и assetInlineLimit

Vite автоматически преобразует небольшие изображения в base64 URI:

import icon from './icon.png'

Если размер файла меньше порога, заданного параметром assetsInlineLimit, изображение будет встроено прямо в Jav * aScript:

const icon = "data:image/png;base64,..."

Это уменьшает количество HTTP-запросов и ускоряет загрузку при условии, что ресурс действительно мал.

Конфигурация:

export default {
  build: {
    assetsInlineLimit: 4096
  }
}

Типичная стратегия:

  • иконки и мелкие UI-элементы — инлайн
  • фотографии и крупные изображения — отдельные файлы

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

Современные пайплайны в Vite часто дополняются конвертацией изображений в более эффективные форматы:

  • WebP
  • AVIF
  • оптимизированный JPEG

Это реализуется через плагины, например vite-imagetools.

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

import img from './photo.jpg?w=800&format=webp'

Здесь применяется трансформация на этапе сборки:

  • изменение размера
  • конвертация формата
  • сжатие качества

Такой подход позволяет генерировать несколько версий одного изображения под разные устройства.

Генерация responsive изображений

Поддержка адаптивных изображений строится через генерацию наборов srcset:

import imgSet from './photo.jpg?w=400;800;1200&format=webp'

Результат:

<img
  src="photo-800.webp"
  srcset="
    photo-400.webp 400w,
    photo-800.webp 800w,
    photo-1200.webp 1200w
  "
>

Это позволяет браузеру самостоятельно выбирать оптимальный ресурс в зависимости от плотности экрана и ширины viewport.

Ключевой эффект — снижение трафика без изменения логики приложения.

Lazy loading изображений

Vite не навязывает поведение загрузки изображений, но хорошо сочетается с нативным lazy loading:

<img src="/large.jpg" loading="lazy">

При использовании импортированных ресурсов:

import img from './large.jpg'

imgElement.loading = 'lazy'
imgElement.src = img

Lazy loading особенно эффективен в сочетании с code splitting, когда изображения подгружаются вместе с динамическими модулями.

Работа с SVG

SVG в Vite можно использовать несколькими способами:

Как URL

import icon from './icon.svg'

Используется как обычное изображение.

Как компонент (через плагин)

С использованием vite-plugin-svgr:

import Icon from './icon.svg?react'

И далее:

<Icon />

Это позволяет:

  • изменять цвет через CSS
  • управлять размерами через props
  • анимировать отдельные части SVG

Inline SVG

import svg from './icon.svg?raw'

Используется для прямой вставки в DOM:

element.innerHTML = svg

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

Плагины оптимизации обычно подключаются через vite-plugin-imagemin:

import imagemin from 'vite-plugin-imagemin'

export default {
  plugins: [
    imagemin({
      mozjpeg: { quality: 75 },
      pngquant: { quality: [0.7, 0.9] }
    })
  ]
}

Основные эффекты:

  • уменьшение размера JPEG/PNG
  • удаление метаданных
  • оптимизация палитры
  • сжатие без значимой потери качества

Такая обработка выполняется только в production-сборке.

Использование import.meta.glob для изображений

Vite поддерживает массовый импорт изображений через glob:

const images = import.meta.glob('./assets/*.jpg', {
  eager: true,
  as: 'url'
})

Результат — объект с URL всех изображений:

{
  './assets/1.jpg': '/assets/1.3f2a1.jpg',
  './assets/2.jpg': '/assets/2.9c1b7.jpg'
}

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

Object.values(images).forEach(src => {
  const img = document.createElement('img')
  img.src = src
  document.body.appendChild(img)
})

Этот подход удобен для:

  • галерей
  • динамических списков
  • автоматической регистрации ассетов

Кеширование и хеширование файлов

Каждое изображение, проходящее через Vite build pipeline, получает уникальный хэш в имени файла:

photo.4d1c9e8a.jpg

Это обеспечивает:

  • долгосрочное кеширование в браузере
  • мгновенное обновление при изменении файла
  • отсутствие ручного versioning

В связке с CDN это позволяет агрессивно кешировать изображения без риска устаревших версий.

Base path и корректная генерация URL

При деплое на поддиректорию важно учитывать base:

export default {
  base: '/app/'
}

Vite автоматически корректирует пути к изображениям:

/app/assets/image.hash.jpg

Без этого изображения могут ломаться при размещении приложения не в корне домена.

Preload и критические изображения

Для ускорения отображения критичных изображений используется preload:

<link rel="preload" as="image" href="/hero.jpg">

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

import hero from './hero.jpg'

const link = document.createElement('link')
link.rel = 'preload'
link.as = 'image'
link.href = hero
document.head.appendChild(link)

Это уменьшает время до первого рендера визуально важных элементов.

Комбинированные стратегии оптимизации

Практическая оптимизация изображений в Vite строится не на одном инструменте, а на сочетании механизмов:

  • разделение public и assets
  • inline для мелких файлов
  • responsive srcset
  • конвертация в WebP/AVIF
  • lazy loading
  • кеширование через хэши
  • оптимизация через плагины
  • preload для критических ресурсов

Каждый слой решает отдельную задачу: сеть, рендеринг, хранение или адаптивность.