Optimización SVG: técnicas para reducir de 100KB a 10KB

Utilidades

La necesidad de optimizar SVG

Los SVG sin optimizar contienen mucha información redundante—metadatos del editor, atributos predeterminados, precisión excesiva, espacios en blanco.

Origen Tamaño típico Optimizado Reducción
Exportación de Figma 45KB 5KB 89%
Exportación de Illustrator 80KB 8KB 90%
Exportación de Inkscape 120KB 12KB 90%
SVG escrito a mano 15KB 3KB 80%

1. Limpieza de información redundante

Metadatos del editor

<!-- Información redundante generada por Illustrator -->
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:serif="http://www.serif.com/"
     id="Artboard1"
     serif:id="Artboard 1"
     viewBox="0 0 800 600">
  <!-- serif:id, xmlns:serif etc. son inútiles -->
</svg>

<!-- Optimizado -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
</svg>

Atributos predeterminados

<!-- Los valores predeterminados no necesitan declararse explícitamente -->
<rect x="0" y="0" width="100" height="100" fill="black" stroke="none" opacity="1"/>

<!-- Optimizado -->
<rect width="100" height="100"/>
Atributo Valor predeterminado Condición para eliminar
fill black Heredado del elemento padre
stroke none Sin trazo
opacity 1 Completamente opaco
x / y 0 En el origen
stroke-width 1 Ancho predeterminado
font-size Heredado Igual que el elemento padre

2. Optimización de rutas

Reducción de precisión

<!-- 6 decimales de precisión excesiva -->
<path d="M12.345678 23.456789 L34.567890 45.678901"/>

<!-- 2 decimales suelen ser suficientes (unidades del sistema de coordenadas SVG) -->
<path d="M12.35 23.46L34.57 45.68"/>
Precisión Tamaño Diferencia visual
6 decimales 100% Ninguna
3 decimales 60% Ninguna (invisible en viewport de 1000px)
2 decimales 50% Mínima
1 decimal 40% Aceptable para iconos pequeños

Fusión de comandos

<!-- Múltiples comandos L se pueden fusionar -->
<path d="M10 20 L30 40 L50 60 L70 80"/>

<!-- Fusionado (L implícito) -->
<path d="M10 20 30 40 50 60 70 80"/>

Simplificación de curvas

<!-- Curva Bézier compleja -->
<path d="M0 0C0.12 0.34 0.45 0.67 1 1C1.34 1.23 1.56 1.78 2 2"/>

<!-- Si la curvatura se aproxima a una línea recta, se puede simplificar a L -->
<path d="M0 0L1 1 2 2"/>

3. Fusión de formas

Fusión de elementos con el mismo estilo

<!-- Tres círculos con el mismo estilo -->
<circle cx="10" cy="10" r="5" fill="red"/>
<circle cx="30" cy="10" r="5" fill="red"/>
<circle cx="50" cy="10" r="5" fill="red"/>

<!-- Fusionados en un solo path -->
<path d="M5 10a5 5 0 1 0 10 0a5 5 0 1 0-10 0M25 10a5 5 0 1 0 10 0a5 5 0 1 0-10 0M45 10a5 5 0 1 0 10 0a5 5 0 1 0-10 0" fill="red"/>

Reutilización con <use>

<!-- Elementos repetidos referenciados con <use> -->
<defs>
  <circle id="dot" r="5" fill="red"/>
</defs>
<use href="#dot" x="10" y="10"/>
<use href="#dot" x="30" y="10"/>
<use href="#dot" x="50" y="10"/>

4. Optimización automática con SVGO

Instalación

npm install -g svgo

Uso desde la línea de comandos

# Optimizar un solo archivo
svgo input.svg

# Especificar salida
svgo input.svg -o output.svg

# Optimización por lotes
svgo -f ./icons/

# Ver efecto de la optimización
svgo input.svg --show-results

Archivo de configuración

// svgo.config.js
module.exports = {
  multipass: true,  // Optimización en múltiples pasadas
  plugins: [
    'removeDoctype',
    'removeXMLProcInst',
    'removeComments',
    'removeMetadata',
    'removeEditorsNSData',
    'cleanupAttrs',
    'mergePaths',
    'convertShapeToPath',
    'convertTransform',
    'removeUnusedNS',
    'minifyStyles',
    'removeEmptyAttrs',
    'removeEmptyContainers',
    'removeHiddenElems',
    'cleanupNumericValues',
    {
      name: 'cleanupNumericValues',
      params: { floatPrecision: 2 },
    },
    {
      name: 'convertPathData',
      params: {
        floatPrecision: 2,
        transformPrecision: 2,
        makeArcs: true,
      },
    },
    'removeDimensions',  // Eliminar width/height, usar viewBox
    'removeViewBox',     // O conservar viewBox, eliminar dimensions
  ],
};

API de Node.js

const { optimize } = require('svgo');

const result = optimize(svgString, {
  path: 'icon.svg',
  multipass: true,
  plugins: [
    { name: 'cleanupNumericValues', params: { floatPrecision: 2 } },
  ],
});

console.log(result.data); // SVG optimizado

5. Optimizar SVG con la herramienta

Pasos

  1. Abre la herramienta de formateo SVG
  2. Pega o sube el código SVG
  3. Haz clic en el botón "Optimizar"
  4. Compara antes y después de la optimización:
    • Tamaño original → Tamaño optimizado
    • Porcentaje de reducción
  5. Copia el resultado optimizado o descárgalo

6. Optimización de SVG Sprite

Sprite en línea

<!-- Definiciones SVG ocultas -->
<svg style="display:none">
  <symbol id="icon-home" viewBox="0 0 24 24">
    <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
  </symbol>
  <symbol id="icon-search" viewBox="0 0 24 24">
    <path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0016 9.5 6.5 6.5 0 109.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5z"/>
  </symbol>
</svg>

<!-- Uso -->
<svg><use href="#icon-home"/></svg>
<svg><use href="#icon-search"/></svg>

Generación automática de Sprite

// Usar svg-sprite para generar automáticamente
const SVGSprite = require('svg-sprite');

const config = {
  mode: {
    symbol: true,  // Generar modo <symbol>
  },
  svg: {
    xmlDeclaration: false,
    doctypeDeclaration: false,
  },
};

const spriter = new SVGSprite(config);
// Agregar archivos SVG y compilar

7. Lista de verificación de optimización de rendimiento

Elemento de optimización Efecto Prioridad
Eliminar metadatos del editor -20~40% P0
Reducir precisión numérica -10~30% P0
Fusionar comandos de ruta -5~15% P1
Eliminar atributos predeterminados -5~10% P1
Convertir formas a rutas -5~10% P2
Eliminar espacios/comentarios -2~5% P2
Compresión Gzip/Brotli -50~70% P0

Nota: SVG es un formato de texto, la compresión Gzip/Brotli es muy efectiva. Asegúrate de habilitarla en el servidor.

#SVG#图片优化#图标#压缩#前端