原文地址:https://segmentfault.com/a/1190000038458838
作者:Fw恶龙
本文首发于:思否
一、前言
关于 WebP 的支持情况,以及适用场景此处不做详细说明,具体见官方文档。
先说结论,目前 WebP 支持情况占比较大(数据如下),在适合的场景下可以使用 WebP 格式图片来提高页面加载速度。
- 支持的浏览器占比达到近90%(数据来源:Can I Use)
- 安卓系统下大部分浏览器已支持,而安卓系统在国内移动端系统中占比达80%(数据来源:statcounter)
- iOS14+ 已经支持 Webp 格式。Added WebP image support.
目前使页面支持 WebP 格式图片有两种方式:
- 前端开发过程生成对应格式图片并编写 WebP 相关代码(本文介绍)
- 服务器端支持生成 WebP 格式图片,前端编写相关加载代码(这部分未深入研究)
二、压缩效果
设置压缩质量为81时,可以在尺寸和质量两者间取得较好的平衡。(测试结果与图片类型以及色彩丰富度有关,具体的压缩质量可以根据实际情况自行调整)
三、在开发中如何使用?
1. html
<picture>
标签会根据浏览器支持情况加载对应资源。
<picture>
<source srcset="./webp/demo.webp" type="image/webp">
<img src="./images/demo.png"/>
</picture>
2. css
通过 js 检测当前浏览器是否支持 WebP 格式的图片(细节见下文 js 代码),在 html 标签上动态添加类名 webp/no-webp,根据浏览器支持情况加载不同格式的图片。
.box {
width: 5.73rem;
height: 6.57rem;
background-repeat: no-repeat;
background-size: 100% 100%
}
.no-webp .box {
background-image: url(../images/demo.png);
}
.webp .box {
background-image: url(../webp/demo.webp)
}
3. js
通过创建 canvas 标签生成 WebP 格式图片,根据其是否生成成功,来判断浏览器是否支持 WebP 格式的图片。
var isSupportWebp = function () {
if(document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0) {
document.getElementsByTagName('html')[0].classList.add('webp');
console.warn("No support webp");
} else {
document.getElementsByTagName('html')[0].classList.add('no-webp');
console.warn("Support webp");
}
}
isSupportWebp();
20201221 更新
Firefox 65 与 iOS 14+ 已经支持 webp 格式,但是以上方法仍然返回 false,故采用官方提供的方法(异步)
function check_webp_feature(feature, callback) {
var kTestImages = {
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
};
var img = new Image();
img.onload = function () {
var result = (img.width > 0) && (img.height > 0);
callback(feature, result);
};
img.onerror = function () {
callback(feature, false);
};
img.src = "data:image/webp;base64," + kTestImages[feature];
};
check_webp_feature('lossy', function(type, support) {
if(support) {
document.getElementsByTagName('html')[0].classList.add('webp');
console.info('Support webp ' + type);
} else {
document.getElementsByTagName('html')[0].classList.add('no-webp');
console.warn('No support webp ' + type);
}
});
四、开发流程
以下流程仅提供大致思路,具体的 webpack 相关配置会根据项目有所出入。
- 设计稿产出 jpg/png 格式切片
- 开发过程使用 webpack 插件 imagemin-webp-webpack-plugin 根据切片自动生成 WebP 格式的切片
- html 底部引入上文对应的 js 检测代码
- html 中的
<img>
标签改为使用<picture>
标签 css 通过预处理器封装背景相关样式的函数,以下为 stylus 代码
bg-webp($url, $ext = png) .no-webp & background-image url($baseUrl + $url + "." + $ext) .webp & background-image url($baseUrlWebp + $url + ".webp")
五、注意事项
1. 以下使用方式会导致 WebP 图片变大
- 引入渐进式的 jpg/png 格式的图片(WebP 不支持渐进式格式)
- 引入已经压缩过的图片(webpack 无法判断该图片是否压缩过)
2. 使用场景
适合
- 较大的图片,如:背景图
不适合
- 小图不建议使用,差别不大
- canvas 等合成图片的还未尝试,因涉及跨域、兼容性等问题,暂时不使用
六、相关文档
- imagemin-webp-webpack-plugin:用于生成 WebP 格式图片
- write-file-webpack-plugin:使得在开发环境中能够正常生成 WebP 格式图片
- copy-webpack-plugin:复制原始图片资源,以触发 imagemin-webp-webpack-plugin
- webp图片在项目中的实践:前端以及服务器端的使用方式
- 判断浏览器是否支持 webp 的几种解决方法
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。