聊一聊web图片小知识
在上家公司做的分享,整理下分享给大家,需要40页的PPT可加V(V798595965)联系(有摸鱼群🐳),or公众号 点击直达回复【图片PPT】即可获取,兄弟姐妹顺便帮小弟点个赞
一、背景
1.1 为什么选这个主题
- 项目有较多处理图片的场景,补齐下相关知识点
- 当时比较热门的几个话题,都能和图片能扯一扯关系,有点兴趣就去了解了下
- 西安电信一码通项目此前报道中提到「两天两夜把 1m 图片优化到100kb」,图像压缩技术难度是怎样的?
- 西安一码通崩溃闹大后,某地区直接【物理】负载均衡
1.2 带着问题看
- GIF都糊成马赛克了,为什么还没怎么见过高清的?
- JPEG 和 JPG有没有区别?什么区别?渐进式图片?
- PNG为什么透明?
- 什么是高斯模糊吗?
- 图片原生支持响应式的方法?
- 我们可以用
<img>
标签可以做哪些技术方案? - .......
二、图片类型
直接开讲,说到图片类型,大家可能立刻会想到的是jpg,png等,这些都算是图片格式,实际上图片有两种类型:
- 位图
- 矢量图
2.1 位图
位图(bitmap)BMP,亦称为点阵图像或栅格图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。
2.2 矢量图
矢量图(vector),也称为面向对象的图像或绘图图像,在数学上定义为一系列由点连接的线。矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。
简单来说矢量图就像用几何图形来描述一幅图,在矢量图放大时,我们所记录的几何图形的各种角度、形状等并没有改变,所以无论是放大还是缩小,都不会影响矢量图的清晰度。对前端而言,能接触到的就是SVG格式了。
2.3 类型对比
- 位图的放大质量较差,但是矢量图可以不降低质量地无限放大。
矢量图 | 位图 | |
---|---|---|
色彩 | 少 | 多 |
空间 | 小 | 大 |
转换 | 可随意转为位图 | 转矢量图难度较大,也无法达到高质量 |
使用场景 | 标识、图标、Logo等简单直接的图像 | 网络中比较丰富的图片中 |
三、图片压缩
3.1 无压缩
无压缩的图片格式不对图片数据进行压缩处理,能准确地呈现原图片。例如BMP格式的图片。
3.2 有损压缩
指在压缩文件大小的过程中,损失了一部分图片的信息,也即降低了图片的质量(即图片被压糊了),并且这种损失是不可逆的。
常见的有损压缩手段是按照一定的算法将临近的像素点进行合并。压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节。因此有损压缩可以在同等图片质量的情况下大幅降低图片的体积。例如jpg格式的图片使用的就是有损压缩。
3.3 无损压缩
在压缩图片的过程中,图片的质量没有任何损耗。我们任何时候都可以从无损压缩过的图片中恢复出原来的信息。
压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的体积。例如png、gif使用的就是无损压缩。常用的压缩图片网站:tinify.cn/
3.4 压缩插件
- imagemin api简洁好用
- compressorjs 有线上预览,感觉不错
- localResizeIMG 国内小哥写的,但是停止维护了
- image-webpack-loader webpack 图片压缩插件
- 了解JS压缩图片,这一篇就够了 带你实现一个js压缩插件,写的挺好,有张图生动形象
项目中可压缩的时机也比较多,本地开发时压缩、打包时压缩、上传OSS压缩、Nginx资源压缩等等,可根据自己需求选择适合自身业务需求的。
四、图片格式
4.1 JPEG
问题1:JPEG和JPG有没有区别?
早期的DOS、Windows 95系统时代的“8.3文件名命名原则”(文件名不能超过8个字符或4个汉字) ,而扩展名不能超过3个字符,中间用小数点“.”分隔。但JPEG是4个字符组成的,无奈只能把4个字符变成3个字符,因此“JPG”格式就诞生了。
问题2:为什么JPG占有率这么大?
JPEG文件对于绝大多数文件通常都很小。 它的压缩使用有损算法,通过牺牲人眼不太敏感的区域的质量来最小化大小。
JPEG的压缩并不是对于所有图像都很管用,对于具有锐利边缘和颜色比较少的图像,JPEG并不是非常管用。常见的例子就是包含文字的图片,另一个是徽标:
问题3:你知道JPG还分了两种格式吗?
一种是线性加载(Baseline JPEG),一种是渐进式加载(Progressive JPEG),两者之间的视觉差异是加载图像的方式。 随着数据的到达,线性加载从上到下加载图像。 渐进式加载以非常低的质量一次打印整个图像,并且随着数据的到达,图像得到了改善。 这里是展示差异的动画:
渐进式图片一开始大小框架就定好,不会像基本式图片一样,由于尺寸未设定而造成回流——提高的渲染性能;渐进式图片也有不足,就是吃CPU吃内存。
4.2 GIF
GIF具有无损压缩和有损压缩的混合特性。像素表示形式是无损的,但是颜色深度限制为每个像素8位,采用的是Lempel-Zev-Welch(LZW)压缩算法,最高支持256种颜色。这意味着文件将包含较少的颜色,但文件体积更小。 这是24位PNG和8位GIF之间的色彩表示的比较。
mac预览打开会变成帧(一直下↓键,就可以动起来了)
4.3 PNG
问题1:PNG为什么可以透明?
PNG是一种非常流行的无损压缩格式,所有的浏览器都支持这种格式。 其设计目的是试图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。PNG使用从LZ77派生的无损数据压缩算法。PNG图片主要有三个类型,分别为 PNG 8/ PNG 24 / PNG 32。 位数越高,存储的颜色就越多(2^n),同时占用的体积也越大
- 在线PS网站:www.photopea.com/
- 在线图片处理工具网站:remove-white-background.imageonline.co/cn/
APNG
APNG 全称是 Animated Portable Network Graphics , 是 PNG 格式的动画扩展,其简单说就是多张PNG合成的动图。可以看下下面两张对比图:
很明显,GIF边缘泛白的情况很突出,APNG就没有这样的问题。在线demo:PNG 对比 APNG 预览,感兴趣的也可以自己去做一个APNG图片:APNG在线合成下载工具。也可以看看这篇科普文科普(APNG) - B站一个有趣的解释
MNG
问题2:既然APNG相比GIF怎么完美,为什么没人用?
动态图虽然广受欢迎,互联网对其的需求也很大,但画质不是决定性因素。看有人这样说:即便是GIF这样糟糕的画质,人们也是乐此不彼的去欣赏一幅GIF中讲述的事情,所以画质不是动图的主要关注点
相关博文
4.4 WEBP
概念
WebP是由Google最初在2010年发布,目标是减少文件大小。它能同时支持无损压缩和有损压缩。它几乎集成了以上所有图片的优点,并且能够拥有更高的压缩率。
看一个统计(比较早的了):YouTube 的视频略缩图采用 WebP 格式后,网页加载速度提升了 10%;谷歌的 Chrome 网上应用商店采用 WebP 格式图片后,每天可以节省几 TB 的带宽,页面平均加载时间大约减少 1/3;Google+ 移动应用采用 WebP 图片格式后,每天节省了 50TB 数据存储空间。
转换
通过vue-webp-plugin和webp-loader 可以在打包阶段进行图片格式的转换,优化项目体积,提升用户体验。不过格式的转换一般用在CDN平台,在一个图片管理平台,生成不同场景下需要的不同格式。如果公司还没有,搭建一个这样的平台,又是一个可搞的小基建🤠
兼容性
都2022年了,兄弟们,放自己一马
4.4 SVG
SVG格式比较特殊,与其他格式有很大不同。 SVG图像存储的是几何形状,而不是每个像素的值。 它的主要优势是可以无限放大而不会造成质量损失,具体可以看下图的对比:
SVG文件类型主要用于徽标,但也用于几何形状的图像。 这种文件的主要缺点是:
对于徽标等小图片,文件大小通常比PNG或WebP大,尤其对于形状复杂,不规则的logo。在大多数情况下,无法将图片有效地转换为SVG(有一些工具说可以做到这一点,但效果并不理想)。
不论视图大小如何,SVG文件的图像质量都很高。 所有现代浏览器都支持它。
4.5 其他格式
其他的格式在图像质量和文件大小方面都更好(BPG, JPEG 2000, JPEG XR),但因为某些格式受专利保护,无法在网络上广泛使用。
- AVIF:下一代图片压缩格式–AVIF来了! 基于一种名为AV1的视频压缩技术的图片格式,还没见过谁在用。。。
- 各种格式的对比:
五、img标签的应用
5.1 img属性
- src 注意在vue和react中的路径问题
- alt 在图片不能正常显示时出现的文本提示
- title 在鼠标在移动到元素上的文本提示
- width、height、border 提前设置好标签宽高,可以减少重绘次数,如果html标签都支持这种写法就舒服了
- loading 懒加载,srcset 响应式,都是实验性属性,不大好用的感觉
- onload、onerror
5.2 发起跨域请求
- crossorigin
- img的这个属性可以控制是否支持cors来获取图像资源,该属性支持两个值:anonymous 和 use-credentials
- anonymous
- 执行一个跨域请求获取资源,但不可以携带cookie、证书或者 HTTP 基本验证信息
- use-credentials
- 跨域请求获取资源,可以携带cookie、证书或者 HTTP 基本验证信息 利用这些属性,我们可以用img做一些环境嗅探相关技术方案(比如曝光埋点),只能发送get请求,拿不到响应,一般只需求在onload和onerror监听请求是否成功即可
5.3 相关css
background
相信大哥们都懂这个,就简单列举下属性
- background-color
- background-image
- background-repeat
- background-attachment
- background-position
div {background:#ffffff url('img_tree.png') no-repeat right top;}
background-size
- 设置背景图片拉伸效果
- cover: 缩放背景图片以
完全覆盖背景区
,可能背景图片部分看不见 - contain:缩放背景图片以
完全填充背景区
,可能背景区部分空白 - 单个具体数值,eg:background-size: 50% 设置图片的宽度
- 两个具体数值,eg:background-size: 50% auto 设置图片的宽高
object-fit
- 指定元素的内容应该如何去适应指定容器的高度与宽度,对图片进行剪切,保留原始比例。挺有用的,学到就是赚到。
- 和background-size区别,可用于img, video等的标签,background-size只能用于背景图
- object-fit & object-position 在线体验demo
filter
- css3的filter真的是无敌
- 可以实现图片模糊、高亮、调色、阴影等各类效果,像手机中的各类滤镜都可以用用这个来搞一搞
- CSS filter demo
img {
filter: grayscale(1); // 黑白
filter: blur(4px); // 模糊
filter: brightness(200%); // 高亮
filter: contrast(200%); // 对比度
filter: drop-shadow(8px 8px 10px red); // 阴影
filter: filter: hue-rotate(90deg); // 色相旋转
filter: filter: invert(100%); // 反转输入图像
filter: filter: opacity(30%); // 透明度
filter: saturate(800%); // 饱和度
filter: contrast(200%) brightness(150%); // 使用多个滤镜,每个滤镜使用空格分隔
}
六、性能&体验优化
6.1 懒加载
监听可视区域
// 监听页面滚动
// 在一开始加载的时候
<img data-src="http://xx.com/xx.png" src="" />
// 在进入可视范围内时
<img data-src="http://xx.com/xx.png" src="http://xx.com/xx.png" />
//可视区域的高度
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
//元素距离可视区域顶部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top;
// 可根据设置距离顶部多少时开始图片加载
Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
img元素Loading 属性
- 图片原生懒加载lazy loading演示 - 张鑫旭 不知道为啥不生效?
<img src="image.jpg" alt="..." loading="lazy">
<iframe src="video-player.html" title="..." loading="lazy"></iframe>
基于IntersectionObserver交叉API实现
Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。
懒加载基础实现
let images = document.querySelectorAll(".lazyload");
let observer = new IntersectionObserver(
(entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
item.target.src = item.target.dataset.src; // 开始加载图片,把data-src的值放到src
observer.unobserve(item.target); // 停止监听已开始加载的图片
}
});
},
{
rootMargin: "0px 0px -100px 0px", // 交叉过视图的100,才开始派发事件
}
);
images.forEach((item) => observer.observe(item));
6.2 高斯模糊
高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作“高斯分布”,所以这项技术就叫作高斯模糊。
原理
- 渲染一个容器,保持与原图的比例和尺寸相同,填充一个较浅的背景色;
- 先加载小图,同时使用模糊效果;
- 小图加载完成,开始请求大图;
- 大图加载完成,显示大图,隐藏小图。
效果
点击预览 progressive image demo For Vanilla JS
6.3 小图片转base64
提升性能: 网页上的每一个图片,都是需要消耗一个 http 请求下载而来的, 图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,base64 可以随着 HTML 的下载同时下载到本地,减少 https 请求。
// 将项目中小于 10kb 的图片转化为 base64 应用到页面中
module.exports = {
...
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 1024,
name: utils.assetsPath('img/[name].[hash:7].[ext]'),
}
},
],
},
}
6.4 响应式图片加载
在不同分辨率的设备上显示不同尺寸的图片,避免资源的浪费。常用的方法就是 css3 的媒体查询
@media screen and (min-width: 1200px) {
img {
background-image: url('1.png');
}
}
@media screen and (min-width: 992px) {
}
@media screen and (min-width: 768px) {
}
@media screen and (min-width: 480px) {
}
还可以使用 HTML5 的 picture 标签进行响应式处理,现在也有一些呼声说可以用picture代替img,目前看picture除了不支持IE,其它支持的都挺好,有相关需求的兄弟们可以用起来了
<picture>
<source srcset="src/img/l.png" media="(min-width: 1200px)" />
<source srcset="src/img/2.png" media="(min-width: 992px)" />
<source srcset="src/img/4.png" media="(min-width: 768px)" />
<img src="src/img/4.png" />
</picture>
6.5 骨架屏
6.6 图片生成服务
有赞微商城包括了 PC 端、H5 端和小程序端,每个端都有绘制分享海报的需求。最早的时候是在每个端通过canvas API来绘制的,通过canvas绘制有很多痛点,于是乎就有了海报生成服务的出现,简单对比下两种实现:
海报服务流程图
服务优化
- 优化Chromium启动项,启动一个最小化可用的浏览器实例,其他不需要的功能都禁用掉,这样会大大提升启动速度
- 每次绘制采用新开标签页的行为,而不是新开一个实例
- Chromium定时刷新机制
- Redis缓存,避免重复绘制
6.7 其它优化点
- 图片预加载:利用浏览器空闲时间,做后台请求图片资源,借助preload,prefetch提高图片加载层级,实现预加载
- 使用css代替某些图片,比如实现修饰效果,如半透明、边框、圆角、阴影、渐变等,在当前主流浏览器中都可以用 CSS 达成,这样能减少图片的请求,达到优化的目的。
- 使用iconfont
- 升级Http2.0(长连接,多路复用,首部压缩,服务端推送等)
- 等等
七、参考 & PPT
- Web性能优化:图片优化
- Web 上的图片技巧
- 前端该如何选择图片的格式
- 需要PPT可加V联系(有摸鱼群🐳),or公众号 点击直达回复【图片PPT】即可获取
八、往期回顾
转载自:https://juejin.cn/post/7116715255404691493