引言
图片的使用在我们日常开发中非常的普遍,常见的场景就是UI给我们什么图,我们用什么图。图太大,让UI压缩一下 重新给一份。不知道你是否思考过UI给的图就一定符合使用场景吗?
在这篇文章中将介绍一些基础的图片知识点。首先介绍两组术语。
光栅图 和 矢量图
光栅图由二维的像素网格组成。每个像素存储了颜色和透明度的值,它并不能很好的支持缩放。JPEG(jpg)、PNG、WEBP等都属于此类
矢量图由一些线条、形状和路径点组成。矢量图的各种信息并不是保存在像素点中,而是保存在精确的绘画指令中,而这些指令是完全独立于像素的。SVG 就是一种矢量图。
有损压缩 和 无损压缩
有损压缩可对文件进行高度压缩从而得到一个更小的压缩文件,但始终有一部分原有像素、声音片段或者视频帧会永久的丢失。JPEG 是目前人们见的最多的有损图片类型。
无损压缩在压缩的过程中则不会出现数据丢失的情况。这意味着压缩不会造成文件质量的削减。但也正是因为如此,无损文件的体积一般要比有损文件大。最常见的无损图片格式是 GIF 和 PNG。
日常开发涉及的图片格式
JPEG
JPEG 是由 Joint Photographic Experts Group 所开发出的一种有损图片。
优点:
- 压缩率高
- 兼容性好
- 色彩丰富
缺点
- 不支持透明
- 有损压缩
- 不支持动画
PNG
PNG(Portable Network Graphics),便携式网络图形,是一种采用无损压缩算法的位图格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。
PNG格式有8位、24位、32位三种形式,其中8位PNG支持两种不同的透明形式(索引透明和alpha透明),24位PNG不支持透明,32位PNG在24位基础上增加了8位透明通道,因此可展现256级透明程度。
PNG图像在浏览器上采用流式浏览,即使经过交错处理的图像会在完全下载之前提供浏览者一个基本的图像内容,然后再逐渐清晰起来
优点
- 无损压缩
- 支持透明
缺点
- 相对比体积大
WebP
WebP 是一种新型的图片格式,可以为网站上的图片提供卓越的无损和有损压缩。使用 WebP,网站站长和 Web 开发者可以制作更小、更丰富的图片,从而提升网页加载速度。
WebP 无损图片的大小比 PNG 图片小 26%。WebP 有损图片比采用等效 SSIM 质量索引的同类 JPEG 图片缩小 25-34%。
无损 WebP 支持透明度(也称为 Alpha 通道),费用仅为 22% 的额外字节。在可以接受有损 RGB 压缩的情况下,有损 WebP 也支持透明度,其提供的文件大小通常比 PNG 小 3 倍。
优点
- 支持有损压缩和无损压缩
- 同等质量体积小
- 支持动画
缺点
- 存在兼容性
SVG
可缩放矢量图形(Scalable Vector Graphics,SVG)基于 XML 标记语言,用于描述二维的矢量图形。
SVG 格式提供的是矢量图,这意味着它的图像能够被无限放大而不失真或降低质量,并且可以方便地修改内容,无需图形编辑器
优点
- 矢量图 放大不失真
- 体积小,Svg 平均比 GIF、 JPEG、 PNG 小得多
- 与DOM无缝衔接
- 支持动画
缺点
- SVG复杂度高会减慢渲染速度
- 不适合游戏类等高互动动画
GIF
GIF是一种索引色模式图片,所以GIF每帧图所表现的颜色最多为256种。GIF能够支持动画,也能支持背景透明。
优点:
- 支持动画和透明背景
- 兼容性好
- 灰度图像表现佳
缺点
- 最多支持 8 位 256 色,色阶过渡糟糕,图片具有颗粒感
- 支持透明,但不支持半透明,边缘有杂边
Base64
图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址,图片随着 HTML 的下载同时下载到本地,不再单独消耗一个http来请求图片。
优点
- 无额外请求
- 没有跨域问题,无需考虑缓存、文件头或者cookies问题
缺点
- 相比其他格式,体积会至少大1/3
- 编码解码有额外消耗
ICO
ICO (Microsoft Windows 图标)文件格式是微软为 Windows 系统的桌面图标设计的。其主要用来做网站图标。通常在网站的根目录下提供一个名为 favicon.ico,最为网站导航栏标签中的图标。
图片优化
图片的优化方式有很多,大概为以下几种
- 选择正确的图片格式
- 选择正确的图片压缩级别
- 提供响应式图片
- 使用CDN图片
- 图片懒加载
- 缩略图
着重于图片懒加载进行说明。
图片懒加载
最常见的延迟加载图像是在 <img> 元素中使用的图像。常用的方法有 使用浏览器级懒加载、使用 Intersection Observer 。
浏览器级延迟加载
Chrome 和 Firefox 都支持通过 loading 属性实现延迟加载。此属性可以添加到 <img> 元素中。 lazy 会值告诉浏览器,如果图像位于时区,则立即加载图像,并在用户滚动到它们附近时获取其他图像。
Intersection Observer
为填充 <img> 元素的延迟加载,我们使用 JavaScript 来检查它们是否位于视区。若位于视区,则会向它们的 src (有时是srcset )属性填充那些指向所需图像内容的 URL。
Intersection Observer 是浏览器新提供的API 不同于之前的监控 scroll 事件 调用 getBoundingClientRect API 获取数值进行条件判断,具有代码简洁 和 性能提升。
以上主要是针对 <img> 标签,但很多图片是被当作背景图使用的。其实现方法原理是相同的。使用 JavaScript 来检查元素是否位于视区中(使用 Intersection Observer!),然后在元素位于视区时添加 background 属性 这时会加载图像。
LazyLoad
最近基于 Intersection Observer 封装了一版 React Hook 的 LazyLoad。支持图片标签、背景图、组件等懒加载功能。同时进行了兼容 API 处理。核心代码如下
写在最后
如果你觉得不错,你的一赞一评就是我前行的最大动力。