假设我们在不同的设计应用程序中绘制相同的矢量图形,并将每个图形导出为 SVG 以在 Web 上使用。我们是否应该期望从每个应用程序获得相同的 SVG 文件?
一方面,我们可能会期望每个文件都相同,因为我们过去导出图像的经验。应用程序通常在保存 JPG、PNG 和 GIF 时保持一致,可能只是总体文件大小略有不同。
另一方面,SVG 与我们通常的图像文件不同,我们的期望可能需要适应这些差异。SVG 的输出可能是视觉上的,但我们真正谈论的是数学和代码。这意味着 SVG 文件更类似于从预处理器编译的 CSS 文件。根据用于编译代码的方法,您的结果可能会有所不同。
我决定在 Illustrator、Sketch 和 Figma 中绘制相同的插图,并比较导出的 SVG 代码。这篇文章将总结这些结果。
关于插图
它并不花哨。一个基本的加号,白色填充,位于黑色填充的圆圈之上。这个想法是使用一些类似于任何网站上常见的图标的东西。

插图绘制了三次,每个应用程序一次。在一个应用程序中创建图标,然后将其复制粘贴到另一个应用程序中,似乎不是一个公平的比较。这允许每个应用程序根据其自己的原生工具来解释 SVG。我不是最熟练的插画师,所以我制作了一个插图,然后在其他应用程序中对其进行描摹,以确保所有内容都按比例缩放,并且所有点几乎都相同。
关于比较
值得注意的是,这篇文章根本不关心该组的“最佳”导出。更有趣的是(1)SVG 代码的编译方式是否存在差异,以及(2)这些可能的差异如何影响前端工作流程,甚至影响哪个应用程序更适合特定项目。
以下是正在比较的内容
- 文件大小
- 代码结构
- 命名规范
还有一点需要提及的是,在此比较中,我们假设使用默认导出选项。Illustrator 有一套强大的选项,可以完全改变 SVG 文件的保存方式,而其他应用程序则没有。我决定使用默认的 Illustrator 导出设置,除了在导出时不缩小代码外。
都准备好了吗?让我们看看结果。
并排代码比较
这是在 2017 年编写的。像这样的应用程序在不断发展。例如,Figma 发布了关于他们对 SVG 导出所做的改进的博文。SVG 有 直接认可的优化插件。而且您应该 始终优化您的 SVG! 💪
表格比较
比较 | Illustrator | Sketch | Figma |
---|---|---|---|
导出设置 | 是 | 否 | 否 |
文件大小 | 498 字节 | 946 字节 | 1 KB |
XML 头 | 否 | 是 | 否 |
包含 和 属性 | 否 | 是 | 是 |
包含viewBox 属性 | 是 | 是 | 是 |
SVG ID | 是 | 否 | 否 |
SVG ID 名称 | 生成 | NA | NA |
SVG 数据名称属性 | 图层名称 | NA | NA |
标题标签(<title> ) | 文件名 | 画板名称 | 图层名称 |
描述标签(<description> ) | NA | 使用 Sketch 创建 | 使用 Figma 创建 |
包含定义(<defs> ) | 否 | 是 | 是 |
包含组(<g> ) | 是 | 是 | 是 |
组 ID 名称 | NA | 按页面名称、画板、组,然后图层组织 | 按框架、组,然后图层组织 |
包含使用(<use> ) | 否 | 否 | 是 |
比较总结
这些结果非常有趣。就像我之前提到的,这里的目标不是宣布谁做得最好™,而是要衡量是否存在差异——当然存在差异!
文件大小
总的来说,SVG 的一个巨大优势是它与光栅图像相比的文件大小很小。这三种情况都体现了这一优势。例如,在 Sketch 中导出为 PNG 的相同图标大小为 12KB。Sketch 的 SVG 输出比其 PNG 对应物节省了 97% 的空间。
我不确定这里三个结果之间文件大小的差异是否都那么重要,尽管事实上 Illustrator 的输出导致的文件大小比 Figma 的输出小约 30%。我之所以这样说,是因为在生产中使用的 SVG 文件很可能会以与使所有这些都变得微不足道的方式相同的方式进行缩小和缓存。
也就是说,文件大小存在差异这一事实可能会影响您用于 SVG 工作流的构建工具以及该构建工具的设置配置方式。
代码结构
文件大小的差异实际上归结于每个应用程序构建其编译代码的方式。例如,Figma 非常注重对形状和路径进行分组和定义,以便在不同的上下文中更方便地重复使用它们,而 Illustrator 完全避免了这些操作,并且倾向于使文件更容易内联。
同样,目标不是确定哪种方法更好,而是认识到生成的文件中存在不同的理念,并以此来帮助确定当前工作的正确工具。根据您的需求和优先级,您可能在一个实例中获得更小的文件大小,但在另一个实例中获得更多灵活性。
命名规范
另一个例子是 Illustrator 默认如何在<svg>
元素上使用唯一的生成 ID。这使得内联文件不太可能与其他内联文件冲突,在这些文件中,设计人员可能在多个文件中使用了相同的文件、画板或图层名称。相比之下,Sketch 和 Figma 都不直接在 SVG 元素上使用 ID。
有一些构建工具可以帮助创建 ID 和类名称,但是,如果您需要手动编辑 SVG 文件或出于某种原因必须使用提供的文件,那么了解应用程序如何命名事物可能会影响您处理工作的方式。
总结
从这次比较中我获得的最大收获是,提醒自己 SVG 最终是代码。我们用来绘制矢量图形的应用程序只是创建代码的 GUI,并且根据编写代码的人的不同,代码的编写方式也可能不同。
这与类似于CodePen Rodeo(顺便问一下,下一次是什么时候?)的东西没有什么不同,其中提供了一个单一的设计,许多人开始用自己的方式编写代码。没有“正确”的编码方式,但看到不同的人采取不同的路径来实现相同的交付成果很有趣。
通过这个比较强调的底线是,我们不能想当然地认为我们拥有的资源是理所当然的。尽管我们可能很享受机器愿意代表我们做出决定的事实,但前端工作流程仍然是一个压倒性的主观任务,并影响着我们如何完成工作。
Sketch和Figma自动添加的
<desc>
属性的一个副作用是,屏幕阅读器会将此内容读给用户。因此,使用来自这两个软件的未修改文件,将会在您最终布局中包含的每个SVG中,为视障用户默认显示这些产品的广告。什么?没有对Inkscape的爱? :(
对SVG的构建方式有非常精细的详细控制。而且它是开源/免费的。 :)
这是一个总结。我执行了“另存为”>“优化SVG”(默认设置)
大小:667字节
我不够聪明,无法弄清楚其余的东西。:) 但它非常简洁,甚至连空格都被去掉了。干杯!
对于在Sketch中导出SVG的任何人,我建议使用他们为此开发的Compressor插件。
https://github.com/BohemianCoding/svgo-compressor
它对于去除所有无用的额外垃圾(如ID等)非常有用,并且最终比Illustrator在导出时提供了更多的控制。
相同的图像,手动编码
是的!这就是正确的方法——现在使用SVGOMG优化后只有154字节 :)
对于这个练习,我更喜欢这种方式(或者两个
<rect>
),但我比较老派。 :)虽然我处理的大多数SVG内容在概念上都非常简单。
压缩后为154字节。
哈,是的!在我的比较中包含一个手动编码的版本,确实会更突出SVG最终是代码这一重点,并且我们不能总是依赖软件为我们生成的内容。
我一看到顶部的图像,这段代码就出现在我的脑海里。然后我看到使用了多边形和组,心想“那不对”。
太令人满意了!
为什么不这样做
呢?
它将“+”作为单个元素,并使用100×100的画布(使用百分比思考很容易),而不是96*96并带有-16的偏移量。
它也稍微小一点。默认情况下为234b而不是237b,压缩后为147字节,如果缩小画布则为141字节。或者如果要将其制作成16×16用于图标/缩放目的,则为144字节。
Geoff,感谢你的文章。你提到,“应用程序在保存JPG、PNG和GIF方面通常保持一致,文件大小可能只有细微差别。”我不同意这一点。我发现文件大小存在许多不一致(有时非常大),具体取决于文件类型和源应用程序的输出设置(即使/特别是使用应用程序默认设置)。SVG似乎也不例外——尤其取决于用户以及他们如何处理图形的整体构建。
此外——将您从这三个应用程序输出的源文件快速通过SVGOMG(使用默认设置),会得到非常不同的结果——现在显示Sketch获得了比AI更小的文件大小。https://jakearchibald.github.io/svgomg/
Illustrator:311字节
Sketch:244字节
Figma:411字节
使用SVGOMG优化后,与Illustrator(510字节)和Figma(759字节)相比,Sketch的输出具有最小的文件大小(338字节)。
Illustrator
Sketch
Figma
也许我和你在从应用程序导出文件方面有不同的体验。以我的经验,没有两个导出的文件是相同的。它们可能在“视觉上”看起来非常相似(就像SVG一样),但底层代码却大不相同。透明度通常以不同的方式处理,颜色匹配很痛苦,元数据被添加/删除/更改,等等。
不同之处在于,与JPEG相比,我们更有可能在将来的某个时刻依赖SVG的底层代码。因此,我们现在注意到并非所有黑色圆圈都是平等的。
以下是使用Affinity Designer SVG导出得到的结果
大小:726字节
以及相关的代码
感谢这个有趣的比较环节!
这是我对使用Affinity Designer构建此SVG的看法。
根据您的设置,Illustrator确实会导出宽度和高度。
• 如果某些内容已分组,则使用
<g>
• 当使用CSS样式设置类名时,使用
<defs>
• 当“响应式”设置禁用时,使用宽度和高度
我个人发现Illustrator是最灵活的。
通过将尺寸减小到最小的整数,您可以进一步缩小文件大小。因为它是SVG,所以您可以毫无问题地将其放大!
Sketch赢得压缩大小比赛并不令人意外,正如其他评论者所注意到的那样,因为它是在三个应用程序中唯一一个在其输出代码中实际使用
<circle>
原语的应用程序。定义圆圈最有效的方法就是使用<circle>
。事实上,Sketch的未压缩输出之所以输给Illustrator,是因为它在某些奇怪的选择上浪费了大量空间。对所有标记使用显式的
<open>
和</close>
标签尤其奇怪,因为SVG广泛使用可以写成<tag />
的空元素(就像其他两个应用程序一样)。但还包含了那个多余的空<defs></defs>
片段。我想这两种情况都可以用基于模板的生成器来解释,该生成器只是没有针对空元素或不必要的容器进行优化,但我有点想知道这些选择背后是否有某种兼容性原因,尤其是<defs></defs>
。无论如何,所有这些都只是“打包”——就结果的实际代码部分而言,Sketch代码是迄今为止最有效的绘图表示。不将圆圈称为
<circle>
会导致其他两个不得不使用相对复杂的结构来模拟它。(但是,您没有确切说明您在每个应用程序中是如何创建圆圈的,这可能会影响输出的生成方式。也许在适当的情况下,Illustrator和Figma会输出<circle />
标签。)我知道您一开始就说过“这篇文章根本不关心‘最佳’导出”,但在输出比较表中包含文件大小确实会引发对结果进行排名的想法。因此,我认为值得认识到Sketch的输出实际上非常接近人们手动编码以获得相同结果的内容。至少从这个测试来看,Sketch的输出是最容易优化的(正如评论者测试所证实的),即使它自己的SVG代码生成器在效率方面有些欠缺。
我随着时间的推移注意到的一件事是,如果您利用笔划和
viewBox
,可以大大减少SVG插图的大小。而且,一般来说,如果您利用默认值,可以减少代码量。我通过这种方式用不到140个字节的手动编码了一个版本。可以放在一条推文中
新想法!
SVG高尔夫
一个人收到一个迷你高尔夫球洞的矢量图,并必须用最少的代码来复制它。
这三个SVG的比较并不相同。Illustrator版本有两个黑色圆圈和一个白色十字,Sketch版本有一个黑色圆圈和一个白色十字,Figma版本有一个黑色圆圈、一个白色十字和两个浅灰色正方形。它们是这样绘制的,还是Illustrator和Figma中的额外对象是在保存/导出时创建的?
顺便说一下,我在CorelDRAW中创建了相同的对象,它导出的文件大小为1079字节。我发现只有Sketch和CorelDRAW将圆导出为
<circle>
很奇怪。“。我发现只有Sketch和CorelDRAW将圆导出为 。“
我也是 - 我还看到Affinity Designer允许复制为SVG。所以这是奇怪的部分。我做了一个简单的圆圈;复制它并粘贴到我的编辑器中 - 它们在剪贴板中使用复制的代码。然后将文件另存为SVG,我惊讶地发现同一个圆圈被转换为数据。我猜想这两个代码集或两个不同的开发人员负责这些模块。
Illustrator版本中确实有两个圆圈,这很有趣。我已不再拥有源文件,但尝试根据原始图形的描摹重新绘制,这次它只用了一条路径。这也大大减少了文件大小。一定是我的错误,我已经更新了比较笔。好发现!
Figma的矩形有点道理,因为它必须导出框架以及图标。我相信这是一个可以更新的工作流程偏好,但它默认情况下希望包含它,这就是我测试所有三个的方式。
我负责Figma的SVG导入/导出工作。我们正在努力在即将发布的更新中解决许多SVG问题。此更新本来早就发布了,但我们一直在忙于组件、原型设计和开发人员交付等功能。
在SVG中,“defs”和“symbols”是用于对场景进行重复数据删除并组织数据的方法。在简单的示例中,defs块确实会添加更多代码。不过,Figma导出更复杂的内容,但您可以争辩说图标案例可以更好地优化。
SVG文件中创建最多xml文本的两个主要文本内容贡献者。第一个是嵌入式图像(base64编码)。第二个是路径,而基元只是指定路径的快捷方式。SVG“polygon”只是一条没有曲线的路径。
在我查看的一些来自设计工具的第一个SVG导出中,图像和路径甚至没有放入defs块中。同一个4MB的图像以base64编码(使其达到10MB)的方式在文件中嵌入20次。路径被重复内联,使样式数据难以阅读。Illustrator更进一步,可以选择将样式隔离到“style”块中,这些块只是样式的defs。
您可以在优化文件中内联各种内容,但这些都有权衡。像这样的简单示例无法传达重复数据删除的压缩效果,或者手动更改跨文档重复数据删除的数据的便利性。最终,SVG并不是我导出的场景中人类可读或可修改的格式。
因此,概括地说,您不能完全优化以下一项:最终文件大小、可读性、传输和渲染,而不会影响这四件事的某些方面。在Figma的情况下,我们目前(我强调这一点)只有一个导出设置,它必须尝试优化这四件事。
我还想指出,SVG已经20年没有修改了。我们仍在使用1.1规范,我没有看到太多将其向前推进的兴趣。浏览器在这里做了最多的工作,提供了出色的导入和渲染功能。尝试使用大型矢量工具执行相同的操作,您会感到惊讶。一项包含所有内容的测试非常发人深省,而且大多数工具无法读取自己的SVG数据或其他SVG文件。
我喜欢说SVG是一种非常有损的格式,因为当前的设计工具都无法很好地导入SVG。即使您导出漂亮的SVG数据,这也是最大的限制之一。1.1中不存在内外笔划,Android Studio甚至不解析defs,Illustrator导入SVG蒙版时崩溃,Sketch/Illustrator在剪贴板上有SVG时粘贴XML,渐变/图像变换无法导入,图案被跳过,等等。
我很高兴Xcode 9终于支持SVG了。对于某些事物来说,它是一个合理的矢量格式,但矢量工具已经发展到更丰富的数据集,例如Figma中的矢量网络。与PDF相比,SVG具有非常棒的效果系统。PDF的构建并非真正考虑了透明度或屏幕设计。它仍然与打印相关。需要一个更好的矢量格式,我们希望Figma能够解决这个问题。
当我第一次遇到在浏览器中使用矢量格式的想法时,我不得不处理VML,然后因为它正值浏览器大战,所以学习和使用它仅限于某些特定场景(例如公司桌面,您保证可以使用IE4或5浏览器)。然后在SVG开始得到开放浏览器支持之前,出现了一段巨大的空白期。我认为这就是规范没有进步的原因:没有理由。
如今,每个人都使用字体作为图标,甚至这些字体也逐渐转向SVG,因为修改、着色或变化非常容易。工具没有专注于格式本身或提升其功能也就不足为奇了。人们可以用它做的事情令人印象深刻,即使我们希望有可堆叠的笔划、可动画的滤镜和更好的剪切蒙版属性等等。
我想正确的优化策略是尽可能地自动化,然后手动调整,直到达到可接受的限制。如上文线程回复所示,此特定图标有许多想法和变体(有些非常小 - 140字节令人印象深刻!)。但这绝非自动化,因为它需要应用程序了解用户想要实现的目标:有时他们希望在导出中包含所有这些图层和分组,以便他们可以通过样式或脚本对其进行操作。
我必须承认,我之前从未听说过Figma。我的开发机器上安装了Illustrator、Inkscape、Graphic和Gimp以及其他一些矢量应用程序,即使我主要是一名编码员,也仅仅是为了比较和手动调整它们的导出格式,以便我可以进行优化(因为根据我的经验,设计师通常不会进行优化)。Figma在设计工作流程中的定位看起来非常酷。