Встраивание мелких ресурсов: assetsInlineLimit

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


Принцип работы встроенных ресурсов

При импорте файла-ресурса в коде:

import logo from './logo.png'

Vite анализирует размер файла и принимает решение:

  • если размер меньше или равен assetsInlineLimit — ресурс превращается в строку Data URL (обычно base64)
  • если больше — файл выносится в отдельный ассет в папку dist/assets

Пример итогового поведения:

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

или

const logo = "/assets/logo.8f3a9c2d.png"

Параметр assetsInlineLimit

Конфигурация задаётся в vite.config.js:

export default {
  build: {
    assetsInlineLimit: 4096
  }
}

По умолчанию значение составляет 4096 байт (4 KB).

Это означает, что все ресурсы размером до 4 KB будут встроены в код как строки, а более крупные файлы будут вынесены в отдельные файлы сборки.


Как Vite обрабатывает ресурсы на практике

Vite делегирует финальную обработку ассетов Rollup-плагину @rollup/plugin-url-подобного поведения, но с собственной интеграцией. Процесс включает:

  1. Определение типа файла (png, svg, woff2, mp3 и др.)

  2. Проверку размера через assetsInlineLimit

  3. Преобразование:

    • в Data URL (inline)
    • либо в файл в dist/assets

Когда происходит инлайнинг

Инлайнинг применяется не только к import, но и к следующим сценариям:

Импорт в JavaScript

import icon from './icon.svg'

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

background-image: url('./bg.png');

Динамические импорты URL

const imgUrl = new URL('./image.png', import.meta.url).href

Во всех случаях действует единая логика определения размера.


Форматы встроенных данных

При инлайне Vite использует Data URL:

Изображения

data:image/png;base64,...

SVG

SVG может быть:

  • либо base64
  • либо URL-encoded текстом (в зависимости от обработки)

Шрифты

data:font/woff2;base64,...

Аудио

data:audio/mpeg;base64,...

Производственные последствия инлайна

Уменьшение количества HTTP-запросов

Инлайн-ресурсы уменьшают число сетевых обращений, что особенно полезно:

  • для мелких иконок
  • UI-элементов
  • критических изображений

Увеличение размера JS/CSS бандла

Base64 увеличивает размер примерно на 33% по сравнению с бинарными данными. Это может:

  • замедлить загрузку основного бандла
  • ухудшить time-to-interactive при больших объёмах инлайна

Потеря кэшируемости

Отдельные файлы могут кэшироваться браузером независимо. Inline-ресурсы:

  • всегда пересобираются вместе с JS
  • не кэшируются отдельно

Оптимальный выбор порога assetsInlineLimit

Подбор значения зависит от характера приложения:

Малые значения (1024–2048 bytes)

Используются, когда:

  • важна максимальная кэшируемость
  • проект содержит много изображений
  • требуется строгий контроль размера JS

Стандартное значение (4096 bytes)

Подходит для большинства SPA:

  • баланс между количеством запросов и размером бандла
  • безопасное значение по умолчанию

Увеличенные значения (8192+ bytes)

Применяются в случаях:

  • большое количество UI-иконок
  • критичность минимизации запросов
  • специфические условия доставки (например, embedded apps)

Переопределение поведения через import

Помимо глобального лимита, Vite позволяет управлять загрузкой ресурсов явно:

Принудительный URL

import imgUrl from './image.png?url'

Принудительный inline

import imgBase64 from './image.png?inline'

Эти суффиксы имеют приоритет над assetsInlineLimit.


Взаимодействие с именованием файлов

Если файл не инлайнится, он попадает в сборку и получает имя:

dist/assets/logo.8f3a9c2d.png

Формат управляется через:

build: {
  assetsInlineLimit: 4096,
  rollupOptions: {
    output: {
      assetFileNames: 'assets/[name].[hash][extname]'
    }
  }
}

Инлайнинг полностью исключает участие этого механизма, так как файл не создаётся физически.


Особенности работы с SVG

SVG является особым случаем:

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

При инлайне SVG увеличивает HTML/JS размер, но позволяет:

  • изменять цвет через CSS (если встроен как markup)
  • избегать дополнительных запросов

Шрифты и влияние инлайна

Шрифты чувствительны к размеру:

  • маленькие иконные шрифты часто инлайнуются
  • основные веб-шрифты почти всегда выносятся в отдельные файлы

Причина:

  • шрифты редко малы
  • повторное использование кэша критично

Поведение в режиме разработки

В dev-режиме:

  • Vite обычно не создаёт физические файлы для ассетов
  • ресурсы обрабатываются через dev server
  • assetsInlineLimit всё равно учитывается логически

Это означает, что даже в разработке можно увидеть Data URL вместо ссылки.


Влияние на производительность сборки

Инлайнинг влияет на:

Время сборки

  • увеличение inline ресурсов слегка ускоряет I/O (меньше файлов)
  • но увеличивает время трансформации (base64 encoding)

Размер итогового бандла

  • напрямую увеличивается при агрессивном инлайне
  • особенно заметно при большом количестве иконок

Типичные ошибки при использовании

Слишком высокий лимит

Приводит к:

  • раздуванию JS-бандла
  • падению производительности загрузки

Полное отключение инлайна

assetsInlineLimit: 0

Последствия:

  • резкий рост HTTP-запросов
  • ухудшение UX на слабых соединениях

Непонимание влияния base64

Base64:

  • не сжимается gzip так эффективно, как бинарные файлы
  • увеличивает размер даже после сжатия

Рекомендованные практики

  • использовать дефолтное значение как базовую точку
  • повышать лимит только при измеренной необходимости
  • не инлайнить крупные изображения
  • оставлять шрифты и медиа вне inline, если они повторно используются
  • применять ?inline только для критически важных UI-элементов

Связь с общим пайплайном ассетов Vite

assetsInlineLimit является частью общей системы обработки ресурсов, которая включает:

  • резолвинг импортов
  • хеширование файлов
  • оптимизацию через Rollup
  • код-сплиттинг
  • обработку CSS url()

Именно на этом этапе определяется, станет ли ресурс:

  • частью JS/CSS
  • или отдельным файлом в сборке