臃肿的 SVG:The Good, the Bad and the Ugly

SVG: The Good, the Bad and the Ugly

原文链接:www.eisfunke.com/posts/2021/...

原文作者:Nicolas Lenz

译者:菜小鸟魔王

SVG^[1]^,也就是我们常说的 scalable vector graphics(可缩放矢量图形)的缩写,是一种特别设计来存储矢量图像的格式,这些图像可以随意放大缩小而不会失真。这篇文章,我会详细阐述我对SVG的看法,指出它的不足之处,并给出我认为能够提升SVG表现的改进方案。

我已经使用SVG和Inkscape好几年了,经常用它们来绘制草图(sketches)和制作图形(graphics),还喜欢动手编写代码实现SVG内容,这让我既能追求图像绘制的精确性,又能通过编程展现我对代码艺术的热爱。我跟SVG有一种爱恨交织的关系。它确实功能强大,也有一些不错的免费开源工具,但它的格式,坦白说,真的不怎么好看。

The Good

  • 无论是在Adobe Illustrator这样的专业软件中,还是在Inkscape这类免费工具里,甚至是各大浏览器中,SVG格式都能得到很好的支持。
  • 网页标准支持SVG这种数据格式,SVG可以直接嵌入到网页中,而且还能和CSS实现一些"骚操作"。
  • 这种数据格式基于XML,所以SVG的语法让人倍感亲切,具有极强的可扩展性,可以融入XML生态。比如,借助XLink^[2]^,可以轻松地在SVG文件中引用其他elements(译者注:常见的SVG元素包括:<circle><ellipse><rect>等)或definitions(译者注:在SVG中,<defs> 元素用于定义一系列可以被文档其他部分引用的对象。比如渐变 (<linearGradient>, <radialGradient>)、模式 (<pattern>)、符号 (<symbol>)等。);而Inkscape^[3]^则通过自定义的XML标签,让SVG成为了编辑器间进行数据交换的"桥梁"。
  • SVG的功能非常强大,可以用它来做很多事情。这种数据格式不仅支持各种 path types 和shapes(译者注:path types and shapes,路径(<path> 元素)是SVG中最灵活的图形元素,可以绘制几乎任何类型的形状。路径由一系列指令组成,这些指令可以是直线、曲线、弧线等。路径指令的字母(大写或小写)和数值组合在一起形成路径数据字符串。形状(如 <circle><ellipse><rect><line><polyline><polygon>)则是预定义的路径类型,它们提供了绘制常见几何形状的快捷方式。这些形状可以单独使用,也可以组合起来创建更复杂的图形。),还支持文本等功能,更厉害的是,它还能实现动画、渐变、特效等复杂效果。

The Bad

这是网络世界的一种标准数据格式,而如同其他网络标准一样,SVG极其臃肿。SVG 的规范^[4]^长达 826 页,其内容之繁复令人咋舌。不仅如此,由于它基于 XML 并与其他网络标准相互连接融合,使得 SVG 的应用范围变得极其广泛,复杂程度令人目眩。

若想要确保所有的 SVG 文件都能正确渲染,除了要啃下 800 多页的 SVG 规范外,还得额外钻研 20 页的 XLink 规范^[5]^。对了,别忘了还有 CSS。而且 SVG 还支持 JAVASCRIPT,没错,SVG 文件中可以嵌入 <script> 标签^[6]^。

SVG 与网络浏览器简直是天作之合。浏览器们本身就臃肿不堪,早已实现了 CSS 和 JavaScript 等相关功能,而这些技能正是实现完整的 SVG 功能所必需的。SVG 的问题,归根结底,也是整个网络世界存在的问题^[7]^。其应用范围广泛,臃肿且难以使用。

想要在一天、一周甚至一个月内掌握 SVG?这几乎是不可能完成的任务。往往只是实现部分功能,让人难以一窥全貌,也让用户在追求 SVG 文件的跨平台兼容性时,对到底可以使用哪些功能感到迷茫。

再者,SVG 的 XML 基础语法既不美观也不精炼。无论是人工编写还是算法解析和自动化生成,都让人倍感疲惫。

The Ugly

从上述提到的问题中,我们可以聚焦到一个关键点,这正是我在探讨机器语言与人类语言设计差异的文章中^[8]^所深入剖析的:SVG 在其定位上模糊不清,它试图同时迎合机器和人类的需求,然而在两者之间却未能找到平衡点,反而在两个领域都显得力不从心(甚至可以说都很糟糕!)。

SVG 是否能够高效地被机器处理?显然不是,它太臃肿了。开发专门用于解析、渲染和生成 SVG 文件的软件工具,是一项耗时费力的工作。SVG 的语法结构繁复冗长,许多高级功能其实可以通过更基础的元素组合来替代。

那么,SVG 这种格式适合人类直接使用吗?答案依然是否定的。一方面,其复杂的语法结构也不利于人类用户使用;另一方面,它又缺乏一些直接操作时所需的实用功能。如果要寻找一种专为人类设计的图形描述语言,LaTeX 的 TikZ^[9]^ 或许是个学习榜样。尽管在我看来,TikZ 在用户体验等方面还有待提升,但它确确实实是为人而设计的,具备了一系列辅助绘制复杂图形的必备功能。然而,没有人会将 TikZ 代码视作成品图形的交换标准,毕竟没有人愿意去阅读长达 1300 页的产品手册只是为了浏览一张图像。相反,人们会选择将其编译成 PDF 格式(虽然 PDF 本身也存在诸多问题,如格式臃肿等)。如果 SVG 真正致力于为人类用户服务,那么将其转化为机器可读的格式应该是其发展方向,可惜,SVG 并没有做到这一点。它既非纯粹面向机器,也非完全为人类而设,可以说,SVG 陷入"两头不讨好"的尴尬境地。

那么接下来该怎么办呢?

一个明智的选择是设计一种简易的矢量图形交换格式,使机器能够轻松处理。这种格式应尽可能简化功能。也许可以基于JSON,但绝不能基于XML。理想情况下,应该能在几天之内,甚至更快,几小时内,无需借助庞大的XML生态系统库就能实现一个基础的渲染器。贝塞尔曲线(Bezier curves)、椭圆曲线(elliptic curves)、填充(fills)、轮廓(outlines)和渐变(gradients)等基本元素,足以覆盖所有静态SVG的渲染需求。此外,可以考虑通过扩展支持,在独立的文件格式中加入动画效果的矢量图形交换格式,让机器处理变得更简单。

这种精简且边界清晰的格式,应当配备一套严格的标准测试套件,使得能够相对轻松地在浏览器和图像查看软件中集成。用户将能够确信自己的图形作品在各种平台上的表现一致,开发者也不必再为XLink、CSS和JavaScript的兼容性问题头疼。这一方案有望减少数据传输量,降低计算资源消耗。为了确保与SVG的兼容性,可以开发相应的转换编译工具。

这种格式可能成为像 Inkscape 和 Adobe Illustrator 这样面向用户的程序的导出格式。对于喜欢通过编程方式来处理图形的人来说,已有诸如 TikZ、Haskell diagrams^[10]^ 或 Python matplotlib^[11]^ 等工具,它们同样也可以支持导出至新提出的极简交换格式。

我正构想一种以机器为中心的精简向量图形格式 ------------ 有人提议命名为"SlimSVG"(这个名字挺逗的~),并计划开发一套以人类为中心的 Haskell 图形生成库,其目标与前者类似 ------------ 服务于我的个人需求,或许这将成为我在大学的一个科研项目。

简而言之:明确一门语言的定位是服务于人类还是机器,然后聚焦于做好其中一个方向。专注于把一件事情做到极致,而非尝试兼顾却两头不讨好。

文中链接

[1] en.wikipedia.org/wiki/Scalab...

[2] en.wikipedia.org/wiki/XLink

[3] inkscape.org/

[4] www.w3.org/TR/SVG11/RE...

[5] www.w3.org/TR/xlink11/

[6] developer.mozilla.org/en-US/docs/...

[7] drewdevault.com/2020/03/18/...

[8] www.eisfunke.com/posts/2021/...

[9] texdoc.net/pkg/tikz

[10] diagrams.github.io/

[11] matplotlib.org/stable/inde...

原文作者介绍:

Hi! I'm Nicolas. I'm a computer science student in Germany. My main interests are functional programming, type systems, free software and infrastructure -- both in computing and in cities. email: www.eisfunke.com/res/email.p...

P.S. 原文作者没有审校过本译文,且译者在翻译本内容时带有个人对原文的理解。可能理解有误,麻烦请在评论区指出!

相关推荐
开心工作室_kaic14 分钟前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā14 分钟前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年2 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder2 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727572 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
SoaringHeart2 小时前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter
会发光的猪。2 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客3 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
猫爪笔记3 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
前端李易安3 小时前
Webpack 热更新(HMR)详解:原理与实现
前端·webpack·node.js