SVG 优化

SVGO 浏览器版

423 次访问
SVG MINIFIER · SVGO STYLE

SVG 在线压缩

SVGO 风格优化 · 去冗余 / 优化路径 / 压缩属性 · 平均减少 30-60%

输入 SVG

优化选项

关于本工具

了解工具定位 · 使用场景 · 对比优势

用 SVGO 压缩 SVG 文件体积,移除冗余属性、空格和元数据,保留完整矢量结构。前端开发者优化图标库、设计师导出 Web 素材、运维缩小静态资源包,拖拽或选择文件即可处理。所有操作在浏览器本地完成,文件不上传服务器。

使用场景

🎨

网页图标瘦身

前端开发者在构建企业官网时,设计师交付的 SVG 图标集(如社交图标、导航图标)未经优化,单个文件常达 10-50KB。使用本工具批量拖入图标文件,自动移除冗余的编辑器元数据、空分组和未使用的定义,图标体积平均压缩 60%-80%,同时保留矢量清晰度,显著提升页面首屏加载速度。

📱

移动端适配压缩

移动端 H5 活动页设计师,需要将复杂的插画 SVG(含渐变、滤镜)嵌入页面,但原始文件动辄 200KB 以上。本工具在浏览器端直接处理,无需上传至服务器,通过 SVGO 算法精简路径坐标精度、合并相邻路径,将文件压缩至 30-50KB,同时确保在低端安卓机上的渲染兼容性不受影响。

🖥️

UI 组件库清理

产品团队在维护一套含 500+ 个 SVG 图标的组件库时,发现许多图标因多次迭代积累了冗余代码(如重复的渐变定义、空标签)。团队成员无需安装命令行工具,直接在浏览器中逐批拖入图标文件,快速清除冗余属性,使整个组件库的 SVG 总大小从 5.2MB 降至 1.8MB,大幅减少组件库的打包体积。

🛡️

隐私敏感文件优化

设计师在为客户处理含保密品牌标识的 SVG 源文件时,需要优化体积但无法将文件上传到第三方云端服务。本工具完全在浏览器本地运行,所有文件不离开用户设备,可直接拖入优化并下载压缩后的 SVG,兼顾文件瘦身需求与客户数据保密要求。

✏️

设计稿导出后处理

UI 设计师从 Figma 或 Sketch 导出的 SVG 图标,常包含大量设计软件特定的注释和元数据(如 sketch:type、figma-id),这些内容对网页渲染无意义但占用了文件体积。使用本工具一键清理这些冗余元数据,使导出文件体积减少 40%-70%,适合直接交付给前端开发用于生产环境。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具 (SVGO 浏览器版)SVGOMG (svgomg.com)传统方法 (手动优化)
数据隐私纯浏览器端处理,文件不上传服务器纯浏览器端处理,文件不上传服务器文件需交给设计师或开发人员,存在传输与泄露风险
处理速度1 秒内完成,即时反馈1-2 秒内完成,即时反馈数分钟到数小时,取决于人工经验和文件复杂度
离线可用完全离线,无需网络完全离线,无需网络依赖本地软件(如 Illustrator、Inkscape),无需网络
操作门槛零门槛,拖拽或选择文件即可低门槛,提供预设和滑块可调高门槛,需掌握 SVG 结构、路径精简等专业技能
精度控制提供 1-5 级预设,无法自定义参数提供滑块和选项,可精细控制精度完全可控,但依赖个人经验,易出错
批量处理单次处理一个文件单次处理一个文件可批量处理,但需手动重复操作或编写脚本
收费完全免费完全免费需支付设计师/开发人员工时费用,或购买专业软件授权

使用指南

上手步骤 · 输入输出 · 避坑提示

使用步骤

  1. 拖入 SVG 文件或点击上传区域选择文件,支持单文件或多文件批量上传
  2. 勾选优化选项(如移除无用属性、合并路径、压缩精度),默认推荐配置可直接使用
  3. 点击「优化」按钮,工具在浏览器内使用 SVGO 引擎处理,无需上传服务器
  4. 预览优化结果:对比原始与优化后的文件大小、路径数量及视觉差异
  5. 点击「下载」保存单个 SVG,或「批量下载」打包为 ZIP 文件

输入输出示例7 个典型场景,覆盖常规、边界与易错

输入输出说明
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="red"/></svg><svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="red"/></svg>典型场景:简单图形,优化后几乎不变
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>典型场景:图标类 SVG,优化后移除多余空格
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#ff0000"/><stop offset="100%" stop-color="#0000ff"/></linearGradient></defs><rect width="800" height="600" fill="url(#g)"/></svg><svg width="800" height="600" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="red"/><stop offset="100%" stop-color="blue"/></linearGradient></defs><rect width="800" height="600" fill="url(#g)"/></svg>边界 case:渐变颜色名被简化为标准色名
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="#FF0000"/><circle cx="50" cy="50" r="30" fill="#00FF00"/><circle cx="50" cy="50" r="20" fill="#0000FF"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red"/><circle cx="50" cy="50" r="30" fill="#0F0"/><circle cx="50" cy="50" r="20" fill="#00F"/></svg>边界 case:颜色值被缩短为 3 位或标准名
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><text x="5" y="5" font-size="2" font-family="Arial">Hello World</text></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><text x="5" y="5" font-size="2" font-family="Arial">Hello World</text></svg>易错 case:文本内容不会被压缩,保持原样
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><!-- 这是一个注释 --><circle cx="50" cy="50" r="40" fill="red"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red"/></svg>典型场景:注释被移除,减小文件体积
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red" fill-opacity="0.5" stroke="black" stroke-width="2"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red" opacity=".5" stroke="black" stroke-width="2"/></svg>边界 case:fill-opacity 被合并为 opacity

常见错误对照8 个常踩的坑 · 错误 → 修复

1. 将 SVG 代码与 HTML 标签混在一起输入

错误
<div><svg>...</svg></div><p>test</p>
修复
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40"/></svg>

SVGO 只处理纯 SVG 元素,混入 HTML 标签会导致解析失败或输出无效。输入前应只保留 <svg>...</svg> 部分。

2. 使用未转义的 XML 特殊字符

错误
<text>5 < 10 & 3 > 1</text>
修复
<text>5 &lt; 10 &amp; 3 &gt; 1</text>

XML 中 <、>、& 必须转义为 &lt;、&gt;、&amp;,否则解析器会误判为标签或实体开始。

3. 依赖 SVG 内嵌 CSS 或 JS 的交互功能

错误
<svg onload="alert(1)"><style>@import url('evil.css')</style>
修复
<svg><rect width="100" height="100" fill="red"/></svg>

SVGO 默认会移除 onload、onclick 等事件处理器和 @import 规则,因为优化目标是静态图形,保留这些会破坏安全性或导致优化后行为不一致。

4. 输入非标准或过大的 viewBox

错误
viewBox="-99999 -99999 999999 999999"
修复
viewBox="0 0 800 600"

SVGO 的坐标精度默认保留 3-5 位小数,超大 viewBox 会被截断或导致路径数据溢出。应使用合理的坐标范围。

5. 把 SVG 文件路径拖入输入框而非文件内容

错误
C:\Users\me\image.svg
修复
点击“选择文件”按钮上传,或直接粘贴 SVG 文本内容

浏览器端工具无法访问本地文件系统路径,必须通过 File API 读取文件内容或手动粘贴代码。

6. 使用 SVG 1.1 不支持的滤镜或动画属性

错误
<filter id="blur"><feGaussianBlur stdDeviation="3" color-interpolation-filters="sRGB"/></filter>
修复
<filter id="blur"><feGaussianBlur stdDeviation="3"/></filter>

部分属性如 color-interpolation-filters 在 SVG 2 草案中已废弃,SVGO 可能保留但渲染引擎不支持。优化前应确认目标浏览器兼容性。

7. 误以为优化后颜色值会变

错误
输入 fill="#ff0000" 期望输出 fill="red"
修复
输入 fill="#ff0000" 输出仍为 fill="#ff0000"(除非启用颜色精简插件)

SVGO 默认不转换颜色表示法,因为不同工具对命名颜色的解析有差异。需要颜色精简需手动启用 colormin 插件。

8. 在 SVG 中使用外部引用(如 <use href> 跨域)

错误
<use href="https://other-domain.com/icons.svg#icon1"/>
修复
<use href="#icon1"/>(前提是 #icon1 定义在同一个文件中)

SVGO 不处理外部资源引用,且浏览器跨域限制会导致 <use> 无法加载外部 SVG。所有引用应内联在同一文件。

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

size_after = size_before × (1 - reduction_rate)

变量说明

  • size_after — 优化后的文件大小(字节)
  • size_before — 原始文件大小(字节)
  • reduction_rate — 压缩率(0~1,由SVGO算法决定)

示例

原始SVG文件 50KB(51,200字节),SVGO默认配置下压缩率约0.35。则 size_after = 51,200 × (1 - 0.35) = 33,280 字节 ≈ 32.5KB。实际结果因图形复杂度略有浮动。

适用范围

适用于任意SVG文件(含路径、形状、文本、滤镜等元素)。不适用于已高度优化的SVG(如手动精简后的文件),此时压缩率可能低于0.05。基于SVGO v3.0+默认配置,具体压缩率受图形结构影响。

原理图

上传 SVG 文件SVGO 引擎优化下载优化结果所有处理在浏览器本地完成,文件不上传服务器支持批量处理,保留原始文件结构
用户输入 本地处理 输出结果

开发者集成

3 种主流语言 · 复制即用

// 使用 svgo 库优化 SVG(Node.js 环境)
import { optimize } from 'svgo';

const svgString = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="red" />
</svg>
`;

const result = optimize(svgString, {
  multipass: true, // 多次优化直到无法进一步压缩
  plugins: [
    'removeDoctype',
    'removeXMLProcInst',
    'removeComments',
    'removeMetadata',
    'removeEditorsNSData',
    'cleanupAttrs',
    'mergeStyles',
    'inlineStyles',
    'minifyStyles',
    'removeUselessDefs',
    'cleanupNumericValues',
    'convertColors',
    'removeUnknownsAndDefaults',
    'removeNonInheritableGroupAttrs',
    'removeUselessStrokeAndFill',
    'removeViewBox': false, // 保留 viewBox 以保持缩放能力
    'cleanupEnableBackground',
    'removeHiddenElems',
    'removeEmptyAttrs',
    'removeEmptyContainers',
    'mergePaths',
    'convertShapeToPath',
    'convertTransform',
    'removeUnusedNS',
    'sortAttrs',
    'removeDimensions': true // 移除宽高,依赖 viewBox 缩放
  ]
});

console.log('原始大小:', svgString.length, '字节');
console.log('优化后大小:', result.data.length, '字节');
console.log('压缩率:', ((1 - result.data.length / svgString.length) * 100).toFixed(1) + '%');
console.log('优化结果:', result.data);
import subprocess
import tempfile
import os

# 通过命令行调用 SVGO(需先安装:npm install -g svgo)
def optimize_svg(svg_content: str) -> str:
    """使用 SVGO 优化 SVG 字符串"""
    with tempfile.NamedTemporaryFile(suffix='.svg', mode='w', delete=False) as f:
        f.write(svg_content)
        input_path = f.name
    
    output_path = input_path.replace('.svg', '_min.svg')
    
    try:
        # 执行 svgo 命令,禁用移除 viewBox
        result = subprocess.run(
            ['svgo', input_path, '-o', output_path, '--config', '{"plugins":[{"removeViewBox":false}]}'],
            capture_output=True,
            text=True,
            timeout=30
        )
        
        if result.returncode != 0:
            raise RuntimeError(f'SVGO 失败: {result.stderr}')
        
        with open(output_path, 'r') as f:
            optimized = f.read()
        
        return optimized
    finally:
        # 清理临时文件
        os.unlink(input_path)
        if os.path.exists(output_path):
            os.unlink(output_path)

# 示例
svg_input = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="40" fill="#ff0000"/></svg>'
optimized = optimize_svg(svg_input)
print(f'原始: {len(svg_input)} 字节')
print(f'优化: {len(optimized)} 字节')
print(f'结果: {optimized}')
package main

import (
	"fmt"
	"os/exec"
	"strings"
)

// 通过 Node.js 调用 svgo(需先安装 svgo)
func optimizeSVG(input string) (string, error) {
	// 使用 Node.js 内联执行 svgo
	script := fmt.Sprintf(`
const { optimize } = require('svgo');
const result = optimize(%q, {
	multipass: true,
	plugins: [
		'removeDoctype',
		'removeXMLProcInst',
		'removeComments',
		{ name: 'removeViewBox', active: false },
		'cleanupAttrs',
		'mergeStyles',
		'minifyStyles',
		'removeUselessDefs',
		'removeUselessStrokeAndFill',
		'removeEmptyAttrs',
		'removeEmptyContainers',
		'mergePaths',
		'convertShapeToPath',
		'removeUnusedNS',
		{ name: 'removeDimensions', active: true }
	]
});
console.log(result.data);
`, input)

	cmd := exec.Command("node", "-e", script)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("执行 SVGO 失败: %w\n输出: %s", err, output)
	}

	return strings.TrimSpace(string(output)), nil
}

func main() {
	svg := `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <rect x="10" y="10" width="80" height="80" rx="10" fill="blue" />
</svg>`

	optimized, err := optimizeSVG(svg)
	if err != nil {
		fmt.Println("错误:", err)
		return
	}

	fmt.Printf("原始大小: %d 字节\n", len(svg))
	fmt.Printf("优化后大小: %d 字节\n", len(optimized))
	fmt.Printf("压缩率: %.1f%%\n", (1-float64(len(optimized))/float64(len(svg)))*100)
	fmt.Println("优化结果:")
	fmt.Println(optimized)
}

常见问题

8 个高频疑问

这个 SVG 优化工具怎么用?
打开页面后,把 SVG 文件拖拽到虚线框区域,或者点击“选择文件”按钮上传。工具会自动用 SVGO 引擎优化,几秒后右侧会显示优化后的代码和预估节省的体积百分比。点击“复制”按钮把优化后的代码粘贴到项目中,或者点“下载”按钮保存为 .svg 文件。如果文件较大(超过 2MB),处理时间会稍长,请耐心等待进度条走完。
优化后 SVG 图片显示变了,颜色或形状不对,怎么回事?
SVGO 默认会删除冗余属性(如空 <g> 标签、默认值属性、未使用的 ID),如果 SVG 文件本身依赖这些冗余元素实现特定渲染(比如某些 AI 软件导出的文件用空分组控制层级),优化后可能丢失部分样式。解决办法:在高级设置中关闭“移除空元素”或“清理未使用的 ID”选项。另外,如果 SVG 内嵌了 CSS 动画或 JavaScript,SVGO 不会处理这些动态内容,但可能因删除相关属性导致动画失效。
优化后体积没变小多少,甚至变大了,为什么?
SVGO 主要优化路径数据(如合并贝塞尔曲线、简化浮点数精度),对已经很“干净”的 SVG(比如手动编写的代码)优化空间有限。如果原文件已经用其他工具压缩过,再次优化可能只减少 1-5%。另外,如果 SVG 包含大量 Base64 内嵌图片,SVGO 不会压缩图片本身(那是图片压缩工具的活),体积可能不变甚至因重新编码微增。上传前可以先查看源文件:如果路径数据很短但图片数据占大头,建议先用 TinyPNG 等工具压缩图片部分。
这个工具支持批量优化吗?一次能上传多少个文件?
目前只支持单个文件上传。如果需要批量处理,可以尝试其他桌面端工具(如 svgo 命令行工具配合脚本循环处理)。本工具定位是快速在线检查一个文件的效果,适合设计师或开发者在提交代码前做最后一道压缩。如果确实有批量需求,可以在页面反馈区留言,我们会评估是否增加多文件上传功能。
上传的 SVG 文件会被上传到服务器吗?安全吗?
所有处理都在本地浏览器中完成(WASM 执行 SVGO 核心逻辑),文件不会离开你的设备。可以打开浏览器开发者工具的“网络”面板确认:上传文件后没有任何 HTTP 请求发出。即使断网,工具也能正常使用。如果包含敏感信息(如公司 logo 的矢量路径),可以放心使用。
SVG 优化后,在浏览器里显示没问题,但放到打印机或雕刻机里变了,怎么办?
SVGO 默认会移除 <metadata>、<title>、<desc> 等非渲染元素,以及某些 Adobe 私有命名空间属性。如果 SVG 文件包含专为排版软件或 CNC 雕刻机准备的元数据(如颜色标签、材料标记),优化后这些元数据丢失可能导致设备识别异常。解决方案:在高级设置中开启“保留元数据”选项(如果工具提供),或者手动在优化后的代码中添加必要的 <metadata> 标签。
这个工具和 TinyPNG 的 SVG 优化比,哪个效果好?
本工具基于 SVGO,专注于清理和压缩 SVG 代码结构(如删除无用标签、合并路径、精简浮点数),适合追求极致代码体积的场景(如前端页面图标)。TinyPNG 的 SVG 优化更侧重视觉无损压缩,会保留更多冗余以兼容不同渲染引擎。实测对比:对于含大量路径的复杂 SVG(如地图),本工具压缩率通常高 5-15%;对于简单图标(如一个矩形加圆角),两者效果相近。建议两个都用一下,对比输出文件大小和渲染效果后选优。
为什么上传后提示“文件格式不支持”?我的确实是 .svg 文件。
请检查文件扩展名是否被系统隐藏(Windows 默认隐藏已知类型扩展名),有时文件实际是 .svgz(压缩 SVG)或 .ai(Adobe Illustrator 原生格式)但被重命名为 .svg。本工具只接受纯文本格式的 .svg 文件。如果文件以 .svgz 结尾,先用解压工具解压;如果是 .ai 文件,需要在 Illustrator 中“另存为”选择 SVG 格式。另外,如果 SVG 文件损坏(比如 XML 标签不闭合),工具会直接报错,可以先用文本编辑器打开检查文件头部是否以 <?xml 开头。
选择 打开 +新窗口 esc关闭