怎么使用 SVG 作为一个图像占位符
创始人
2024-03-01 21:15:43
0

从图像中生成的 SVG 可以用作占位符。请继续阅读!

我对怎么去让 web 性能更优化和图像加载的更快充满了热情。在这些感兴趣的领域中的其中一项研究就是占位符:当图像还没有被加载的时候应该去展示些什么?

在前些天,我偶然发现了使用 SVG 的一些加载技术,我将在这篇文章中谈论它。

在这篇文章中我们将涉及如下的主题:

  • 不同的占位符类型的概述
  • 基于 SVG 的占位符(边缘、形状和轮廓)
  • 自动化处理

不同的占位符类型的概述

之前 我写过一篇关于图像占位符和 延迟加载 lazy-loading 的文章以及 关于它的讨论。当进行一个图像的延迟加载时,一个很好的办法是提供一个东西作为占位符,因为它可能会很大程度上影响用户的感知体验。之前我提供了几个选择:

在图像被加载之前,有几种办法去填充图像区域:

  • 在图像区域保持空白:在一个响应式设计的环境中,这种方式防止了内容的跳跃。从用户体验的角度来看,那些布局的改变是非常差的作法。但是,它是为了性能的考虑,否则,每次为了获取图像尺寸,浏览器就要被迫进行布局重新计算,以便为它留下空间。
  • 占位符:在图像那里显示一个用户配置的图像。我们可以在背景上显示一个轮廓。它一直显示直到实际的图像被加载完成,它也被用于当请求失败或者当用户根本没有设置头像图像的情况下。这些图像一般都是矢量图,并且由于尺寸非常小,可以作为内联图片。
  • 单一颜色:从图像中获取颜色,并将其作为占位符的背景颜色。这可能是图像的主要颜色、最具活力的颜色 … 这个想法是基于你正在加载的图像,并且它将有助于在没有图像和图像加载完成之间进行平滑过渡。
  • 模糊的图像:也被称为模糊技术。你提供一个极小版本的图像,然后再去过渡到完整的图像。最初显示的图像的像素和尺寸是极小的。为去除 细节 artifacts ,该图像会被放大并模糊化。我在前面写的 Medium 是怎么做的渐进加载图像使用 WebP 去创建极小的预览图像、和渐进加载图像的更多示例 中讨论过这方面的内容。

此外还有其它的更多的变种,许多聪明的人也开发了其它的创建占位符的技术。

其中一个就是用梯度图代替单一的颜色。梯度图可以创建一个更精确的最终图像的预览,它整体上非常小(提升了有效载荷)。

使用梯度图作为背景。这是来自 Gradify 的截屏,它现在已经不在线了,代码 在 GitHub

另外一种技术是使用基于 SVG 的技术,它在最近的实验和研究中取得到了一些进展。

基于 SVG 的占位符

我们知道 SVG 是完美的矢量图像。而在大多数情况下我们是希望加载一个位图,所以,问题是怎么去矢量化一个图像。其中一些方法是使用边缘、形状和轮廓。

边缘

前面的文章中,我解释了怎么去找出一个图像的边缘并创建一个动画。我最初的目标是去尝试绘制区域,矢量化该图像,但是我并不知道该怎么去做到。我意识到使用边缘也可能是一种创新,我决定去让它们动起来,创建一个 “绘制” 的效果。

使用边缘检测绘制图像和 SVG 动画

在以前,很少使用和支持 SVG。一段时间以后,我们开始用它去作为一个某些图标的传统位图的替代品……

形状

SVG 也可以用于根据图像绘制区域而不是边缘/边界。用这种方法,我们可以矢量化一个位图来创建一个占位符。

在以前,我尝试去用三角形做类似的事情。你可以在 CSSConfRender Conf 上我的演讲中看到它。

上面的 codepen 是一个由 245 个三角形组成的基于 SVG 占位符的概念验证。生成的三角形是基于 Delaunay triangulation 的,使用了 Possan’s polyserver。正如预期的那样,使用更多的三角形,文件尺寸就更大。

Primitive 和 SQIP,一个基于 SVG 的 LQIP 技术

Tobias Baldauf 正在致力于另一个使用 SVG 的低质量图像占位符技术,它被称为 SQIP。在深入研究 SQIP 之前,我先简单介绍一下 Primitive,它是基于 SQIP 的一个库。

Primitive 是非常吸引人的,我强烈建议你去了解一下。它讲解了一个位图怎么变成由重叠形状组成的 SVG。它尺寸比较小,适合于直接内联放置到页面中。当步骤较少时,在初始的 HTML 载荷中作为占位符是非常有意义的。

Primitive 基于三角形、长方形、和圆形等形状生成一个图像。在每一步中它增加一个新形状。很多步之后,图像的结果看起来非常接近原始图像。如果你输出的是 SVG,它意味着输出代码的尺寸将很大。

为了理解 Primitive 是怎么工作的,我通过几个图像来跑一下它。我用 10 个形状和 100 个形状来为这个插画生成 SVG:

使用 Primitive 处理 ,使用 10 个形状100 形状原图
使用 Primitive 处理,使用 10 形状100 形状原图

当在图像中使用 10 个形状时,我们基本构画出了原始图像。在图像占位符这种使用场景里,我们可以使用这种 SVG 作为潜在的占位符。实际上,使用 10 个形状的 SVG 代码已经很小了,大约是 1030 字节,当通过 SVGO 传输时,它将下降到约 640 字节。


正如我们预计的那样,使用 100 个形状生成的图像更大,在 SVGO(之前是 8kB)之后,大小约为 5kB。它们在细节上已经很好了,但是仍然是个很小的载荷。使用多少三角形主要取决于图像类型和细腻程度(如,对比度、颜色数量、复杂度)。

还可以创建一个类似于 cpeg-dssim 的脚本,去调整所使用的形状的数量,以满足 结构相似 的阈值(或者最差情况中的最大数量)。

这些生成的 SVG 也可以用作背景图像。因为尺寸约束和矢量化,它们在展示 超大题图 hero image 和大型背景图像时是很好的选择。

SQIP

Tobias 自己的话说

SQIP 尝试在这两个极端之间找到一种平衡:它使用 Primitive 去生成一个 SVG,由几种简单的形状构成,近似于图像中可见的主要特征,使用 SVGO 优化 SVG,并且为它增加高斯模糊滤镜。产生的最终的 SVG 占位符后大小仅为约 800~1000 字节,在屏幕上看起来更为平滑,并提供一个图像内容的视觉提示。

这个结果和使用一个用了模糊技术的极小占位符图像类似。(看看 Medium其它站点 是怎么做的)。区别在于它们使用了一个位图图像,如 JPG 或者 WebP,而这里是使用的占位符是 SVG。

如果我们使用 SQIP 而不是原始图像,我们将得到这样的效果:

第一张图像第二张图像 使用了 SQIP 后的输出图像。

输出的 SVG 约 900 字节,并且通过检查代码,我们可以发现 feGaussianBlur 过滤被应用到该组形状上:


SQIP 也可以输出一个带有 Base64 编码的 SVG 内容的图像标签:


轮廓

我们刚才看了使用了边缘和原始形状的 SVG。另外一种矢量化图像的方式是 “描绘” 它们。在几天前 Mikael Ainalem 分享了一个 codepen 代码,展示了怎么去使用两色轮廓作为一个占位符。结果非常漂亮:

SVG 在这种情况下是手工绘制的,但是,这种技术可以用工具快速生成并自动化处理。

如果感兴趣,可以去看一下 Emil 的 webpack 加载器 (基于 potrace) 和 Mikael 的手工绘制 SVG 之间的比较。

这里我假设该输出是使用默认选项的 potrace 生成的。但是可以对它们进行优化。查看 图像描绘加载器的选项传递给 potrace 的选项非常丰富。

总结

我们看到了从图像中生成 SVG 并使用它们作为占位符的各种不同的工具和技术。与 WebP 是一个用于缩略图的奇妙格式 一样,SVG 也是一个用于占位符的有趣格式。我们可以控制细节的级别(和它们的大小),它是高可压缩的,并且很容易用 CSS 和 JS 进行处理。

额外的资源

这篇文章上到了 Hacker News 热文。对此以及在该页面的评论中分享的其它资源的链接,我表示非常感谢。下面是其中一部分。


via: https://medium.freecodecamp.org/using-svg-as-placeholders-more-image-loading-techniques-bed1b810ab2c

作者:José M. Pérez 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

AI视频时代,谁在闻风而动
当内容产业开始进入AI模型化阶段,大家拼的不仅是流量,也是数据、算...
2025-07-02 14:12:28
开源图像编辑器 GIMP ...
IT之家 6 月 24 日消息,科技媒体 9to5Linux 昨日...
2025-06-24 13:12:59
Midjourney推出A...
新榜讯 当地时间6月19日,Midjourney正式发布其视频生成...
2025-06-20 12:13:09
Midjourney 推出...
IT之家 6 月 19 日消息,热门 AI 图像生成初创公司 Mi...
2025-06-19 11:12:36
Adobe(ADBE.US...
Adobe(ADBE.US)公司于本周二正式推出面向Android...
2025-06-17 23:13:46
泰和观复申请基于图像识别增...
金融界2025年6月7日消息,国家知识产权局信息显示,北京泰和观复...
2025-06-07 22:42:35

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
2024 开年,LLUG 和你... Hi,Linuxer,2024 新年伊始,不知道你是否已经准备好迎接新的一年~ 2024 年,Lin...
什么是 KDE Connect... 什么是 KDE Connect?它的主要特性是什么?它应该如何安装?本文提供了基本的使用指南。科技日...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...