先检查一下你的浏览器是否支持 WebP 格式,如果支持的话,下面加载的图片上就会有小灯里(当然,这张图已经被转成 WebP 格式了),不支持的话图片上的小灯里就是透明人(显示另一张 JPEG 格式的图片)了~
(原图来自
Pixiv ID: 70919335
)
“你们都欺负灯里,好过分啊”
为什么要使用 WebP
WebP 在支持有损、无损、透明图片压缩的同时,大大减少了图片的体积。据统计,WebP 无损压缩后比 PNG 图片体积减少了 26%,有损图片比同类 JPEG 图像体积减少了 25% ~ 34%。
↑懒得自己写介绍了,就直接 复制粘贴 好了~总之 WebP 是一种比 JPEG、PNG、GIF 都不知道高到哪里去了的新型图片格式。
以下面两张文件大小相似的,
被压缩得
惨不忍睹
的高压图
为例进行比较,一张是 19.2 KB 的 JPEG 图片(使用
mozjpeg
压缩),另一张是 19.0 KB 的 WebP 图片。
(原图来自 Pixabay )
(如果看不到图片的话,说明你的浏览器 不支持 WebP ,可以点 这里 查看那张 WebP 图片转换为 PNG 格式后的图)
- 图片上方的天空,JPEG 图片中出现了很明显的色带,但是 WebP 图片中的色带相对来说不怎么明显。
- 图片下方的水波纹和左下角的码头是细节丰富的高频区域,JPEG 图片出现了明显的“小碎块”,但是 WebP 图片上这种现象就并不是十分明显。
- WebP 图片中的小船、码头、建筑物外墙等部分,比 JPEG 图片有更清晰的轮廓。
上面的对比中,WebP 的表现显然要优于 JPEG。适当调节压缩参数的话,将 JPEG 二压成 WebP 还能在一定程度上消除 JPEG 压缩时产生的块状噪点。
即使是使用
TinyPNG
有损压缩(256 色)过的 PNG 图片,再使用 WebP
无损压缩
还能将文件大小继续降低至少 10%。至于 GIF 这种压缩率已经无法
满足人民日益增长的精神文化需要
(各种沙雕图)的动图格式,转换成 Animated WebP 也能进一步降低文件大小。
可以使用更小的文件大小,以更高的质量展示图片,那当然是要资瓷 WebP 格式的啦~
将网页的图片升级成 WebP
小透明一直在使用
ae01.alicdn.com
的接口作为图床(上传接口参见 GitHub 上的项目
upimg
),之前尝试过直接上传
.webp
文件,但是会报错。最近才发现,只要
将文件扩展名修改为
.jpg
、
.png
、
.gif
这些传统格式的扩展名,其实是可以上传任意类型的文件的……所以,把 WebP 图片
修改扩展名为
.jpg
也是可以上传的,当然也可以在网页上正常使用,于是就有了在这里使用 WebP 图片的打算。
9102 年了,隔壁 Firefox 早就加入 WebP 格式的支持了,但是 iOS 上的唯一指定浏览器 Safari(虽然 iOS 上也有 Firefox 和 Chrome,但是 Apple 规定 第三方浏览器必须使用 Safari 内核 )仍然 不支持 WebP (出来挨打!⊂彡☆))д`) ),另外 IE11 也是不支持的。所以使用 WebP 要考虑向前兼容,在不支持的浏览器上应该自动回退到使用 JPEG 等传统图片格式。
后端可以通过请求头中的
Accept
字段判断是否支持 WebP,如果支持的话对应的请求头一般是
Accept: image/webp, */*
,有些 CDN 服务根据这个实现了“自适应 WebP”的功能。不过因为小透明还是在使用公共图床,所以还是得手动生成传统格式和 WebP 两份图片,然后上传两次,在前端使用两个图片链接……
以下两种在前端自动切换 WebP 的方法,均参考自 “把网站的图片升级到WebP格式吧” 这篇文章。
使用 HTML5 中的
<picture>
标签
<picture>
<source srcset="large.jpg" media="(min-width: 800px)">
<source srcset="medium.jpg" media="(min-width: 600px)">
<img srcset="small.jpg">
</picture>
如果在
<picture>
里面加一个使用 WebP 图片的
<source>
,在最后的
<img>
中使用传统格式,这样就可以实现在支持的设备上优先使用 WebP。
<picture>
<source type="image/webp" srcset="image.webp">
<img src="image.jpg">
</picture>
使用 JS 检测 WebP 支持并替换
可以使用 JS 加载一张 1x1 的 WebP 图片,如果浏览器支持 WebP 的话就可以读取到图片的长和宽。
function checkWebp(callback) {
var img = new Image();
img.onload = function () { callback((img.width > 0) && (img.height > 0)); };
img.onerror = function () { callback(false); };
img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
}
<!-- 一般的img标签 -->
<img class="..." src="image.jpg" alt="...">
<!-- 为了使用JS替换WebP图片而使用的标签 -->
<!-- 如果直接将传统格式图片写进src的话一打开网页就会开始加载,切换src后又会加载WebP图片,等于重新加载了两张图片 -->
<img class="..." data-src="image.jpg" data-src-webp="image.webp" alt="...">
// 如果img标签存在WebP图片的地址,就使用它进行替换,否则使用传统格式的图片的地址
// 不影响一般的img标签
function showImage(useWebp) {
var imgs = [].slice.call(document.querySelectorAll('img'));
imgs.forEach(function (e) {
if (useWebp && e.getAttribute('data-src-webp')) {
e.src = e.getAttribute('data-src-webp');