SVGO (SVG Optimizer) — инструмент для уменьшения размера SVG-файлов за счёт удаления лишних данных, преобразования структур и упрощения графики без потери визуального качества. В контексте работы с библиотекой Snap.svg оптимизация SVG играет критическую роль, поскольку напрямую влияет на производительность, скорость загрузки и удобство работы с DOM.
SVG-файлы, экспортированные из графических редакторов (например, Illustrator или Figma), часто содержат:
<g>)id, class,
style)<path>)Это приводит к:
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.config.js:
module.exports = {
multipass: true,
plugins: [
{
name: "removeViewBox",
active: false
},
{
name: "cleanupIDs",
active: true
}
]
};
Удаляет декларацию <!DOCTYPE>:
<!DOCTYPE svg PUBLIC ...>
Удаляет комментарии:
<!-- comment -->
Удаляет блок <metadata>
Удаляет <title> — важно, если используется для
доступности
Очищает и нормализует атрибуты
Преобразует цвета:
#ff0000 → red → #f00
Упрощает данные пути:
M 10 10 L 20 20 → M10 10L20 20
Объединяет несколько <path> в один
Удаляет неиспользуемые namespace
Удаляет неиспользуемые <defs>
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
}
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 }
]
};
{
"scripts": {
"optimize-svg": "svgo -f src/svg -o dist/svg"
}
}
Через svgo-loader:
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: 'svgo-loader',
options: {
configFile: 'svgo.config.js'
}
}
]
}
]
}
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>
Результат:
Причина — удаление важных атрибутов (id,
class, viewBox)
Причина — объединение путей или удаление отдельных элементов
Причина — агрессивная оптимизация path или
transform
Полезно добавить проверку:
svgo input.svg --config=svgo.config.js --pretty
Флаг --pretty помогает визуально проверить
результат.
Если SVG вставляется прямо в HTML:
<svg id="icon"></svg>
SVGO помогает:
После оптимизации SVG можно загружать:
Snap.load("optimized.svg", function(data) {
paper.append(data);
});
Чем чище SVG — тем быстрее выполняется:
select, selectAll)Максимальная оптимизация не всегда полезна. В проектах с Snap.svg важно сохранять:
Оптимизация должна быть контролируемой, а не агрессивной.