前端图片详解(最全面、最新)

前言

当我们在做前端性能优化的时候,总是会离不开图片,尤其在首次内容绘制(FCP)最大内容绘制 (LCP)中,图片显得格外关键,而我发现关于图片格式的文章,一般不全,或者是偏旧。

所以这篇文章,我将把我学过的关于图片的知识,分享给大家

首先我们可以通过HTTP Archive: Page Weight来直观看一下页面的加载体积

总的 web 资源的平均请求体积是这样的

图片资源,平均请求体积是这样的

在这里插入图片描述

我们发现图片在所有资源中所占的比重,是非常惊人的,所以我们来系统地学习一下图片

图片格式

理解像素、颜色和二进制的关系

无论是通过扫描仪、数码相机还是其他图像捕捉设备,图片首先被转换成像素(picture elements)的阵列。每个像素代表图片中的一个小区域,并且拥有特定的颜色信息。

在计算机中,像素二进制数来表示。不同的图片格式中像素与二进制位数之间的对应关系是不同的。一个像素对应的二进制位数越多,它可以表示的颜色种类就越多,成像效果也就越细腻,文件体积相应也会越大。

一个二进制位表示两种颜色(0|1 对应黑|白),如果一种图片格式对应的二进制位数有 n 个,那么它就可以呈现 2^n 种颜色。

颜色通常通过红绿蓝(RGB)模型来表示,每个颜色通道可以有从0到255的值。在二进制中,一个字节(byte)有8位,足以表示0到255的任何值(因为2^8 = 256)。因此,每个颜色通道可以用8位二进制数来表示,例如,红色通道的值255可以表示为二进制的11111111

图片格式

一旦图片被数字化并分配了颜色值,它就可以被保存为不同的文件格式,那么我们常见的图片格式有哪些,使用场景是什么,区别是什么

这里我们首先可以看MDN提供的图像文件类型与格式指南 - Web 媒体技术 | MDN (mozilla.org)

然后我们稍微整理一下,方便大家观看

缩写MIME类型文件扩展名摘要压缩透明度动画
ANPGimage/apng.apng是无损动画序列的良好选择(GIF 性能较差)。AVIF 和 WebP 性能更好,但浏览器支持较少。无损压缩支持支持
AVIFimage/avif.avif由于其性能高,且无需版税,是图像和动画图像的理想选择。与 PNG 或 JPEG 相比,它的压缩效果更好,支持更高的色深、动画帧、透明度等。请注意,在使用 AVIF 时,应包含浏览器支持更好的回退格式(也就是说,要使用 <picture> 元素)。无损压缩支持支持
GIFimage/gif.gif是简单图像和动画的不错选择。无损有索引的静态图像首选 PNG,动画序列可考虑 WebP、AVIF 或 APNG。无损压缩支持支持
JEPGimage/jpeg.jpg、.jpeg、.jfif、.pjpeg、.pjp静态图像有损压缩的理想选择(目前最流行)。如果需要更精确地再现图像,则首选 PNG;如果需要更好的再现效果和更高的压缩率,则首选 WebP/AVIF。有损压缩不支持不支持
PNGimage/png.png与 JPEG 相比,PNG 能更精确地再现源图像,或在需要透明的情况下更受青睐。WebP/AVIF 可提供更好的压缩和再现效果,但浏览器的支持比较有限。无损压缩支持不支持
SVGimage/svg+xml.svg矢量图像格式;适用于用户界面元素、图标、图表等,必须以不同尺寸精确绘制。可以在传输过程中使用 HTTP 压缩技术进行压缩,也可以在磁盘上以 .svgz 文件的形式进行压缩。支持支持
WebPimage/webp.webp是静止图像和动画图像的绝佳选择。WebP 的压缩效果比 PNG 或 JPEG 好得多,而且支持更高的色深、动画帧和透明度等。AVIF 的压缩效果稍好,但在浏览器中的支持度不高,而且不支持渐进式渲染。无损和有损压缩支持支持

图片格式详解

我们梳理一下每个格式的优缺点,然后说一下常见的使用场景

这里我更想对比着说,看着更直观

GIF和ANPG

首先GIF诞生于1987年,APNG相对新一些,是Mozilla在2004年推出的

APNG实际上是PNG的拓展(看名字就看出来了),APNG 新增了三种区段:acTL、fcTL、fdAT,这三个区段不打算细讲,可能讲了大家也不能很好理解

那么可能有人会问,如果设备或者软件不支持ANPG只支持PNG,那怎么办呢

答案是不用担心,ANPG第一帧储存方式和普通的PNG一样在IDAT区段中

在压缩上GIF采用的是LZW(据说之前GIF的LZW算法有专利限制),而APNG采用的是Deflate,经测试,在经过各种优化手段进行压缩后,ANPG的体积是小于GIF的

在颜色和透明度上GIF最多支持256种颜色,进而导致导致了GIF画质都比较差,同时GIF虽然也支持透明,但是他只支持将某个颜色标记成透明,也就是说他不支持半透明,只支持完全透明或者完全不透明,所以会出现杂边问题,这个问题我正好在一篇ANPG的文章中看到了,正好解释一下

在这里插入图片描述

而反观ANPG,则是完全不受限制的

那么ANPG的缺点是什么呢,可能只有兼容性了和普适性问题了吧

关于使用场景,其实因具体情况而异,但是二者基本都用在动态显示

JPEG/JPG

有小伙伴可能一直不清楚JPG和JEPG的区别,这里咱们就稍微说一下

JPEG(全称Joint Photographic Experts Group)和JPG(全称Joint Photographic Experts Group format)实际上是指同一个图像格式,没有本质区别。"JPEG"通常是指这个格式的组织和标准,而"JPG"则是这种格式的文件扩展名。

JPG的优点较为明显:当我们把图片体积压缩至原有体积的 50% 以下时,JPG 仍然可以保持住60%的品质。同时JPG格式以24位存储单个图,可呈现多达1600万种颜色,这也是压缩后,我们肉眼依旧难以察觉的原因

同时JPG/JEPG兼容性非常好,所以经常在网页背景图片轮播图广告和宣传材料等显眼位置看到它的身影

但是它也有较为明显缺点,有损压缩,在压缩过程中会丢失一部分图像数据。虽然这种损失对于肉眼可能不明显,但在多次编辑和保存后,图像质量的下降可能会变得更加明显,以及在处理矢量图形Logo 等线条感较强、颜色对比强烈的图像时,人为压缩导致的图片模糊会相当明显

同时它不适合用于存储简单图形、图标或文字,因为这些类型的图像通常不需要复杂的颜色信息,而JPG的压缩方式可能会导致这些类型的图像模糊

再者它还不支持透明度处理,所以就需要配合别的格式进行使用

PNG-8 与 PNG-24

我们主要用PNG来呈现小的Logo、颜色简单且对比强烈的图片或背景等

说到PNG,基本上就是说PNG-8与PNG-24,说PNG-32的较少那我们就来说说二者的区别

首先PNG后面的8、24数字,意思是指该格式最多可以索引存储的颜色值

PNG-8:最多存储256种颜色,也就是2^8 = 256,2的8次方。

PNG-24最终的,意思是最多存储1600万种颜色,即2^24 = 16 777216种颜色,也就是2的8次方。

再者,二者的透明度不同

PNG-8:仅支持1位的布尔透明通道,不支持半透明效果

PNG-24:支持alpha半透明过渡效果,也就是可以完美呈现从不透明到完全透明的渐变过渡。

最后,二者的压缩率不同,这也导致最终的体积不同,PNG-24最终的体积是比PNG-8要大出不少的,所以PNG-24不适合存储照片等颜色较多、细节丰富的图片,多用于存储需要保留透明度、颜色单一的图片,比如LOGO、图片水印等文件应使用PNG-24存储。

SVG

SVG和上面的JPG和PNG等有些不同,SVG-可缩放矢量图形,为什么它叫做矢量图形

这是因为它的工作原理与传统的位图图形(如JPEG、PNG等)截然不同。矢量图形的核心特点在于它使用数学公式和几何形状来定义图像,而不是像素点的集合。

缩放性SVG图像是基于数学公式的,这意味着它们可以在任何尺寸下无损放大或缩小。无论图像被缩放到多大或多小,都能保持清晰和锐利,不会出现像素化或模糊,1 SVG足以适配n分辨率

小文件尺寸SVG文件通常比位图文件小,因为它们不需要存储每个像素的颜色信息。相反,它们只存储定义图形的数学方程式和属性,这使得文件尺寸更加紧凑。

文本和编码性SVG文件文本文件,使用XML格式编写。这意味着SVG图像可以被编辑器打开和编辑,就像编辑文本文件一样。可以像写代码一样定义 SVG,把它写在 HTML 里、成为 DOM 的一部分,也可以把对图形的描述写入以 .svg 为后缀的独立文件,这种文本基础的特性也使得SVG文件可以被搜索、索引和脚本化。

交互性SVG支持CSSJavaScript,这意味着可以给SVG元素添加样式和行为,从而创建动态和交互式的图形。例如,可以响应用户的操作,如鼠标悬停、点击等事件。

例如:假设我们有一个简单的SVG图标,我们想在鼠标悬停时改变它的颜色

<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="blue" class="hoverable"><title>Hover over me!</title></circle>
</svg><style>.hoverable:hover {fill: red; /* 鼠标悬停时变为红色 */cursor: pointer; /* 鼠标悬停时变为手指形状 */}
</style>

又或者:通过JavaScript为同一个SVG圆添加点击事件,使其在被点击时改变大小

<svg width="100" height="100" id="mysvg"><circle cx="50" cy="50" r="40" fill="blue" class="clickable"><title>Click on me!</title></circle>
</svg><script>var svg = document.getElementById('mysvg');var circle = svg.querySelector('.clickable');circle.addEventListener('click', function() {var currentRadius = parseInt(circle.getAttribute('r'));var newRadius = (currentRadius == 40) ? 60 : 40; // 切换半径大小circle.setAttribute('r', newRadius);});
</script>

再或者:将SVG写入独立文件后引入HTML:

<img src="文件名.svg" alt="">

以上就是简单地举例,目的是为了体现出SVG灵活性

在实际开发中,我们更多用到的是后者。很多情况下设计师会给到我们 SVG 文件,就算没有设计师,我们还有非常好用的 iconfont-阿里巴巴矢量图标库。对于矢量图,我们无须深究过多,只需要对其核心特性有所掌握、日后在应用时做到有迹可循即可。(这段是修言说的,我觉得很好,就摘抄了~)

但是我在使用的时候,也发现了一些SVG的问题:虽然SVG通常比位图图像小,但在描述的矢量元素几何复杂度较高时,基于文本的SVG文件可能比二进制编码的栅格化图像要大(但是的确不能算缺点,只能说不是特别适用)

Base64

Base64其实不是一种图片格式,而是一种编码方法,Base64是为了减少加载网页图片时对服务器的请求次数,从而提升网页性能,它可以将二进制数据(如图片)转换为ASCII字符串。但是会增加页面的总体大小,因为Base64编码后的字符串通常比原始的二进制数据要大(这也是Base64不适用于大图,适用于小图的原因

这种感觉有点类似于雪碧图,但是原理不一样,雪碧图是一种将多个小图片合并到一张大图片中的技术,通过CSS的background-imagebackground-position属性来引用大图中的特定小图片,这样减少了HTTP请求次数,提升了网页加载速度,并且可以提前加载可能需要用到的小图片,减少页面闪烁

二者更像是相辅相成的关系,它们都可以用于优化网页性能,但选择哪一种技术取决于具体的应用场景和需求

WebP和AVIF

二者都是10年后诞生的,我们称之为现代图片格式,它的优点明显,都能覆盖传统格式(JPG、PNG等)的动态图片无损压缩等功能和特性,传统格式特性较为单一,现代格式支持动态图片、无损压缩等特性更多,并且体积变小,相较于jpg格式,webp格式的图片一般能减少10%左右的体积,avif格式更是能减少40%以上的文件体积。

缺点基本就是兼容性(其实WebP还好了,早些年的确兼容性的确不行,现在基本都支持了),这里我们二者进行对比

工作原理上

  • WebP:基于VP8编解码器,使用有损和无损压缩方法的组合来实现更小的文件大小,有损压缩与 JPEG 相似,但增加了优化功能,从而提高了图像质量。它的无损压缩使用一种称为预测编码的技术,该技术可预测相邻像素的值,并只对实际值和预测值之间的差值进行编码。
  • AVIF:使用AV1编解码器,在不影响图像质量的情况下减小文件大小,具有内部预测(根据邻近块预测块的内容)和自适应量化(根据图像的复杂程度调整压缩级别)的功能,既是最先进的又是免版税的。

色彩上

  • WebP:支持8位和10位色深
  • AVIF:支持8位和10位以及12位色深,可见AVIF这个后起之秀,在色彩准确度和鲜艳度方面更胜一筹

这样看来AVIF尤其适用于高质量图像(如照片这种的),而如果需要的是一种通用的图像格式,并能获得广泛的浏览器支持,那么 WebP 就是您的不二之选

用现代图片格式优化性能以及体验

我们经过上面的学习发现,如果能使用webp,avif等现代格式,对解决前端应用图片类资源体积较大,加载耗时较长、CDN开销较高的痛点会有明显优化。那么我们具体怎么做呢?

回答是:<picture>元素

我们看一下MDN对于picture 元素的定义吧

在这里插入图片描述

看起来很懵,什么意思呢

<picture>元素允许同时引入多个图片格式的子元素,并根据浏览器的兼容性,按先后顺序、自适应加载其中1个格式的图片,实现所有用户根据自身兼容性,获取到最优图片格式。

我写一段代码,大家就明白了

<picture><!-- WebP格式的图片,具有无损和有损压缩 --><source srcset="image.webp" type="image/webp"><!-- AVIF格式的图片,具有更高的压缩率 --><source srcset="image.avif" type="image/avif"><!-- JPEG格式的图片,作为备选 --><source srcset="image.jpg" type="image/jpeg"><!-- 如果浏览器不支持上述任何格式,就使用这个img标签作为最后的备选 --><img src="fallback-image.jpg" alt="Description of Image">
</picture>
  • <picture>元素是一个容器元素,元素中包含了2个<source>元素和1个<img>元素。
  • 每个<source>元素都有一个srcset属性,它指定了图片的URL,以及一个type属性,它描述了图片的MIME类型。浏览器会根据这些信息和自身的兼容性来决定加载哪个图片。
  • 如果所有的<source>元素都不被支持,那么<img>元素将作为最后的备选方案。这是一个包含JPEG图片(别的格式也可以,选兼容性好的即可)的<img>标签,相当于一个兜底操作

通过这种方式,可以确保所有用户都能加载到他们设备支持的最佳格式的图片,从而提供更好的网页体验和性能,而大家也不要小瞧这种方式,现在其实是很常用的。

结尾

本文带着大家过一遍常见的图片格式,包括内容优缺点等,希望带着大家了解关于图片的具体内容,其实本来是想着把关于图片的优化都写在这一篇的,奈何实在是过于散乱,配合这篇基础文章显得不合适,所以只介绍了一种较为简单,还能承接上文的<picture>元素的方式给大家

其实关于什么雪碧图之类的网上已有全面的教程,所以不打算写了,而关于什么懒加载的实际上是交互上的优化内容,所以也不会去写

在之后的文章中会接着写一下关于图片的知识点,图片优化实战方面的内容,比如写一下辅助函数配合CDN啦,压缩图片具体操作啦等内容,蟹蟹大家支持~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/306617.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Bitmap OOM

老机器Bitmap预读仍然OOM&#xff0c;无奈增加一段&#xff0c;终于不崩溃了。 if (Build.VERSION.SDK_INT < 21)size 2; 完整代码&#xff1a; Bitmap bitmap; try {//Log.e(Thread.currentThread().getStackTrace()[2] "", surl);URL url new URL(surl);…

数据结构--链式栈

一.链式栈的栈顶在哪里? 二.链栈的结构: typedef struct LSNode{ int data; struct LSNode* next; }LSNode ,*PLStack; //链栈的节点.由于栈顶在第一个数据节点,所以不需要top指针 三.链式栈的实现: //初始化LSNode* p (LSNode*)malloc(sizeof(LSNode));assert(p ! NULL)…

Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066

很奇怪的问题,在使用nifi的时候碰到的,这里是用NIFI,把数据从postgresql中同步到mysql中, 首先postgresql中的源表,中是没有create_time这个字段的,但是同步的过程中报错了. 报错的内容是说,目标表中有个create_time字段,这个字段是必填的,但是传过来的flowfile文件中,的数据没…

Kali中间人攻击

中间人攻击 中间人攻击&#xff08;Man-in-the-Middle Attack&#xff0c;简称MITM&#xff09;是一种网络安全攻击&#xff0c;其中攻击者插入自己&#xff08;作为“中间人”&#xff09;在通信的两个端点之间&#xff0c;以窃取或篡改通过的数据。攻击者可以监视通信&#x…

Composer 安装与使用

文章目录 Composer的主要特点&#xff1a;Composer 的安装Windows 平台Linux 平台Mac OS 系统 Composer 的使用require 命令update 命令remove 命令search 命令show 命令 基本约束精确版本范围通配符波浪号 ~折音号 ^ 版本稳定性 Composer 是PHP编程语言的一个依赖管理工具。它…

【R语言从0到精通】-3-R统计分析(列联表、独立性检验、相关性检验、t检验)

上两次教程集中学习了R语言的基本知识&#xff0c;那么我们很多时候使用R语言是进行统计分析&#xff0c;因此对于生物信息学和统计科学来说&#xff0c;R语言提供了简单优雅的方式进行统计分析。教程参考《Rlearning》 3.1 描述性统计分析 3.1.1 载入数据集及summary函数 我…

广州南沙番禺联想SR530服务器主板传感器故障维修

今日分享一例广州市南沙区联想ThinkSystem SR530服务器sensor sysbrd vol故障问题维修案例&#xff1b; 服务器型号是&#xff1a;Lenovo thinksystem sr530 g6服务器 服务器所在位置&#xff1a;广东省广州市南沙区 服务器故障问题&#xff1a;机房异常停电&#xff0c;来电后…

HarmonyOS开发学习:【DevEco Device Tool 安装配置(问题全解)】

本文介绍如何在Windows主机上安装DevEco Device Tool工具。 坑点总结&#xff1a; 国内部分网络环境下&#xff0c;安装npm包可能会很慢或者超时&#xff0c;推荐使用国内npm源&#xff08;如淘宝源、华为源等&#xff09;&#xff1b;serialport这个npm包安装的过程中需要编…

透视晶圆制造黑匣子:RFID赋能智能生产,构建晶圆盒全程精准追溯体系

透视晶圆制造黑匣子&#xff1a;RFID赋能智能生产&#xff0c;构建晶圆盒全程精准追溯体系 应用背景 在全球半导体产业链中&#xff0c;晶圆盒作为承载硅片的重要载体&#xff0c;其生产过程的精细化管理和追溯显得至关重要。近年来&#xff0c;一种名为RFID&#xff08;Radi…

Fast-lio2运行时如何显示轨迹线

修改对应设备的.yaml文件&#xff0c;以velodyne为例&#xff1a; 将 path_en参数改为true即可&#xff0c;运行其他设备&#xff0c;修改对应的参数

mysql面试题 1

为什么要使用数据库 数据保存在内存 优点&#xff1a; 存取速度快缺点&#xff1a; 数据不能永久保存 数据保存在文件 优点&#xff1a; 数据永久保存缺点&#xff1a;1、速度比内存操作慢&#xff0c;频繁的IO操作。2、查询数据不方便 数据保存在数据库 数据永久保存使用SQL语…

跟TED演讲学英文:The inside story of ChatGPT‘s astonishing potential by Greg Brockman

The inside story of ChatGPT’s astonishing potential Link: https://www.ted.com/talks/greg_brockman_the_inside_story_of_chatgpt_s_astonishing_potential Speaker: Greg Brockman Date:April 2023 文章目录 The inside story of ChatGPTs astonishing potentialIntro…

path环境变量的作用

当我把一个运行文件的路径加入到了path环境变量&#xff0c;就可以在cmd命令行随时使用运行。 在path中有两个path上面的是用户的path&#xff0c;下面的是计算机的path

77、WAF攻防——权限控制代码免杀异或运算变量覆盖混淆加密传参

文章目录 WAF规则webshell免杀变异 WAF规则 函数匹配 工具指纹 webshell免杀变异 php 传参带入 eval可以用assert来替换,assert也可以将字符串当作php代码执行漏洞 php 变量覆盖 php 加密 使用加密算法对php后门进行加密 php 异或运算 简化:无字符webshellP 无数字字母rc…

NAPI 类对象导出及其生命周期管理(下)

4. 样例工程源码剖析 工程的模板是Native C,模型是Stage。源码剖析主要围绕以下几个文件 4.1. NAPI导出对象和生命周期管理具体实现 4.1.1. 定义NapiTest类及方法 Napi.h文件内容如下&#xff1a; #ifndef __NAPI_TEST_H__ #define __NAPI_TEST_H__#include "napi/nat…

Android Studio开发学习(六)———TableLayout(表格布局)、FrameLayout(帧布局)

目录 前言 一、Tablelayout &#xff08;一&#xff09;Tablelayout的相关简介 &#xff08;二&#xff09;TableLayout使用方法 1. 当TableLayout下面写控件、则控件占据一行的大小。(自适应一行&#xff0c;不留空白) 2.多个组件占据一行&#xff0c;则配合TableRow实现…

VulnHub靶机-easy_cloudantivirus 打靶

easy_cloudantivirus 靶机 目录 easy_cloudantivirus 靶机一、导入虚拟机配置二、攻击方式主机发现端口扫描web渗透-SQL注入命令注入反弹shellssh爆破提权 一、导入虚拟机配置 靶机地址&#xff1a; https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453/下载完成&am…

计算机网络-TCP断开连接阶段错误应对机制

连接断开阶段 四次挥手机制&#xff1a;TCP连接的断开需要四次挥手&#xff0c;这是因为双方都需要独立地关闭数据传输。第二次和第三次挥手不能合并&#xff0c;因为在回复第二次挥手的时候&#xff0c;可能还有数据没有接收完成&#xff0c;所以需要先回复ACK报文&#xff0c…

KNN分类算法的MATLAB实现以及可视化

一、KNN简介 KNN算法&#xff0c;即K-Nearest Neighbors&#xff0c;是一种常用的监督学习算法&#xff0c;可以用于分类问题&#xff0c;并且在实际应用中取得了广泛的成功。 二、KNN算法的基本原理 对于给定的测试样本&#xff0c;KNN算法首先计算它与训练集中所有样本的距…

编译器领域一些特别好的文章

xz​​​​​​​s​​​​​​​cv_note/cv算法工程师成长路线.md at master HarleysZhang/cv_note GitHub记录cv算法工程师的成长之路&#xff0c;分享计算机视觉和模型压缩部署技术栈笔记。https://harleyszhang.github.io/cv_note/ - cv_note/cv算法工程师成长路线.md at…