Otimização SVG: técnicas para reduzir de 100KB para 10KB

Utilitários

A necessidade de otimizar SVG

SVGs não otimizados contêm muita informação redundante—metadados do editor, atributos padrão, precisão excessiva, espaços em branco.

Origem Tamanho típico Otimizado Redução
Exportação do Figma 45KB 5KB 89%
Exportação do Illustrator 80KB 8KB 90%
Exportação do Inkscape 120KB 12KB 90%
SVG escrito à mão 15KB 3KB 80%

1. Limpeza de informação redundante

Metadados do editor

<!-- Informação redundante gerada pelo 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. são inúteis -->
</svg>

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

Atributos padrão

<!-- Valores padrão não precisam ser declarados explicitamente -->
<rect x="0" y="0" width="100" height="100" fill="black" stroke="none" opacity="1"/>

<!-- Otimizado -->
<rect width="100" height="100"/>
Atributo Valor padrão Condição para remover
fill black Herdado do elemento pai
stroke none Sem traço
opacity 1 Completamente opaco
x / y 0 Na origem
stroke-width 1 Largura padrão
font-size Herdado Igual ao elemento pai

2. Otimização de caminhos

Redução de precisão

<!-- 6 casas decimais de precisão excessiva -->
<path d="M12.345678 23.456789 L34.567890 45.678901"/>

<!-- 2 casas decimais geralmente são suficientes (unidades do sistema de coordenadas SVG) -->
<path d="M12.35 23.46L34.57 45.68"/>
Precisão Tamanho Diferença visual
6 casas 100% Nenhuma
3 casas 60% Nenhuma (invisível em viewport de 1000px)
2 casas 50% Mínima
1 casa 40% Aceitável para ícones pequenos

Fusão de comandos

<!-- Múltiplos comandos L podem ser fundidos -->
<path d="M10 20 L30 40 L50 60 L70 80"/>

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

Simplificação de curvas

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

<!-- Se a curvatura se aproxima de uma reta, pode ser simplificada para L -->
<path d="M0 0L1 1 2 2"/>

3. Fusão de formas

Fusão de elementos com o mesmo estilo

<!-- Três círculos com o mesmo 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"/>

<!-- Fundidos em um único 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"/>

Reutilização com <use>

<!-- Elementos repetidos referenciados com <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. Otimização automática com SVGO

Instalação

npm install -g svgo

Uso pela linha de comando

# Otimizar um único arquivo
svgo input.svg

# Especificar saída
svgo input.svg -o output.svg

# Otimização em lote
svgo -f ./icons/

# Ver efeito da otimização
svgo input.svg --show-results

Arquivo de configuração

// svgo.config.js
module.exports = {
  multipass: true,  // Otimização em múltiplas passadas
  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',  // Remover width/height, usar viewBox
    'removeViewBox',     // Ou manter viewBox, remover dimensions
  ],
};

API do 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 otimizado

5. Otimizar SVG com a ferramenta

Passos

  1. Abra a ferramenta de formatação SVG
  2. Cole ou faça upload do código SVG
  3. Clique no botão "Otimizar"
  4. Compare antes e depois da otimização:
    • Tamanho original → Tamanho otimizado
    • Percentual de redução
  5. Copie o resultado otimizado ou baixe

6. Otimização de SVG Sprite

Sprite inline

<!-- Definições 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>

Geração automática de Sprite

// Usar svg-sprite para gerar automaticamente
const SVGSprite = require('svg-sprite');

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

const spriter = new SVGSprite(config);
// Adicionar arquivos SVG e compilar

7. Lista de verificação de otimização de performance

Item de otimização Efeito Prioridade
Remover metadados do editor -20~40% P0
Reduzir precisão numérica -10~30% P0
Fundir comandos de caminho -5~15% P1
Remover atributos padrão -5~10% P1
Converter formas em caminhos -5~10% P2
Remover espaços/comentários -2~5% P2
Compressão Gzip/Brotli -50~70% P0

Nota: SVG é um formato de texto, a compressão Gzip/Brotli é muito eficaz. Certifique-se de habilitá-la no servidor.

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