SVGO

SVGO (SVG Optimizer) — инструмент для уменьшения размера SVG-файлов за счёт удаления лишних данных, преобразования структур и упрощения графики без потери визуального качества. В контексте работы с библиотекой Snap.svg оптимизация SVG играет критическую роль, поскольку напрямую влияет на производительность, скорость загрузки и удобство работы с DOM.


Зачем нужна оптимизация SVG

SVG-файлы, экспортированные из графических редакторов (например, Illustrator или Figma), часто содержат:

  • избыточные метаданные
  • комментарии
  • неиспользуемые группы (<g>)
  • лишние атрибуты (id, class, style)
  • дублирующиеся или неоптимальные пути (<path>)

Это приводит к:

  • увеличению размера файла
  • замедлению загрузки
  • усложнению манипуляций через Snap.svg

SVGO устраняет эти проблемы автоматически.


Установка SVGO

SVGO распространяется как npm-пакет:

npm install -g svgo

Локальная установка:

npm install svgo

Проверка установки:

svgo --version

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

Оптимизация одного файла:

svgo input.svg

Результат перезапишет исходный файл. Чтобы сохранить в другой:

svgo input.svg -o output.svg

Оптимизация директории:

svgo -f ./icons

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

SVGO настраивается через файл svgo.config.js:

module.exports = {
  multipass: true,
  plugins: [
    {
      name: "removeViewBox",
      active: false
    },
    {
      name: "cleanupIDs",
      active: true
    }
  ]
};

Основные параметры:

  • multipass — многократная оптимизация (глубже, но медленнее)
  • plugins — список плагинов для обработки SVG

Ключевые плагины SVGO

removeDoctype

Удаляет декларацию <!DOCTYPE>:

<!DOCTYPE svg PUBLIC ...>

removeComments

Удаляет комментарии:

<!-- comment -->

removeMetadata

Удаляет блок <metadata>

removeTitle

Удаляет <title> — важно, если используется для доступности

cleanupAttrs

Очищает и нормализует атрибуты

convertColors

Преобразует цвета:

#ff0000 → red → #f00

convertPathData

Упрощает данные пути:

M 10 10 L 20 20 → M10 10L20 20

mergePaths

Объединяет несколько <path> в один

removeUnusedNS

Удаляет неиспользуемые namespace

removeUselessDefs

Удаляет неиспользуемые <defs>


Особенности при работе со Snap.svg

Snap.svg активно взаимодействует с DOM-структурой SVG. Некоторые оптимизации SVGO могут нарушить ожидаемую структуру.

Важные ограничения:

1. Не удалять id, если используются в коде

snap.select("#circle")

Для этого отключается плагин:

{
  name: "cleanupIDs",
  active: false
}

2. Сохранять viewBox

Snap.svg использует viewBox для масштабирования:

paper.attr({ viewBox: "0 0 100 100" });

Отключение удаления:

{
  name: "removeViewBox",
  active: false
}

3. Осторожно с группами <g>

Плагин collapseGroups может разрушить иерархию:

{
  name: "collapseGroups",
  active: false
}

4. Не объединять пути при анимации

Если используется анимация отдельных элементов:

element.animate({ d: ... })

Плагин mergePaths лучше отключить:

{
  name: "mergePaths",
  active: false
}

Пример конфигурации для Snap.svg

module.exports = {
  multipass: true,
  plugins: [
    { name: "removeDoctype", active: true },
    { name: "removeComments", active: true },
    { name: "removeMetadata", active: true },
    { name: "cleanupAttrs", active: true },
    { name: "convertColors", active: true },
    { name: "convertPathData", active: true },

    { name: "removeViewBox", active: false },
    { name: "cleanupIDs", active: false },
    { name: "collapseGroups", active: false },
    { name: "mergePaths", active: false }
  ]
};

Интеграция в рабочий процесс

Через npm-скрипты

{
  "scripts": {
    "optimize-svg": "svgo -f src/svg -o dist/svg"
  }
}

Использование в сборщиках

Webpack

Через svgo-loader:

module: {
  rules: [
    {
      test: /\.svg$/,
      use: [
        {
          loader: 'svgo-loader',
          options: {
            configFile: 'svgo.config.js'
          }
        }
      ]
    }
  ]
}

Gulp
const gulp = require('gulp');
const svgo = require('gulp-svgo');

gulp.task('svg', () => {
  return gulp.src('src/svg/*.svg')
    .pipe(svgo())
    .pipe(gulp.dest('dist/svg'));
});

Практическое влияние оптимизации

До оптимизации:

<svg width="100px" height="100px">
  <g>
    <path d="M 0 0 L 100 100"></path>
  </g>
</svg>

После SVGO:

<svg viewBox="0 0 100 100">
  <path d="M0 0L100 100"/>
</svg>

Результат:

  • уменьшение размера файла до 30–70%
  • сокращение DOM-узлов
  • ускорение работы Snap.svg

Частые ошибки

Потеря функциональности после оптимизации

Причина — удаление важных атрибутов (id, class, viewBox)

Ломается анимация

Причина — объединение путей или удаление отдельных элементов

Некорректное отображение

Причина — агрессивная оптимизация path или transform


Рекомендации

  • всегда хранить оригинал SVG
  • тестировать после оптимизации
  • использовать кастомную конфигурацию
  • отключать плагины, влияющие на структуру DOM
  • минимизировать изменения, если SVG активно управляется через Snap.svg

Автоматизация контроля качества

Полезно добавить проверку:

svgo input.svg --config=svgo.config.js --pretty

Флаг --pretty помогает визуально проверить результат.


Работа с inline SVG

Если SVG вставляется прямо в HTML:

<svg id="icon"></svg>

SVGO помогает:

  • уменьшить HTML-размер
  • ускорить рендеринг
  • упростить структуру для Snap.svg

Совмещение с Snap.svg

После оптимизации SVG можно загружать:

Snap.load("optimized.svg", function(data) {
  paper.append(data);
});

Чем чище SVG — тем быстрее выполняется:

  • выбор элементов (select, selectAll)
  • анимации
  • манипуляции атрибутами

Баланс между оптимизацией и управляемостью

Максимальная оптимизация не всегда полезна. В проектах с Snap.svg важно сохранять:

  • идентификаторы элементов
  • логическую структуру
  • отдельные узлы для анимации

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