鉴于之前做的大屏的项目,全屏背景图过大,传统的写法导致页面渲染过慢,因而非常影响用户体验。
除此以外,很多时候在开发过程中会出现很多图片的情况,图片过多或大,会直接影响页面的响应时间,从而导致页面性能变差。
针对以上,我们可以使用WebP来有效的改善。
WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器宽带资源和数据空间。
WebP既支持有损压缩也支持无损压缩。相较编码JPEG文件,编码同样质量的WebP文件需要占用更少的计算资源。
目前Chrome、Oprea以及较高版本的火狐等是支持WebP的,其实这个数量也一直在增加,未来可能会有更好的兼容性。
不过就目前来看,在使用webp的同时,还是需要对其不兼容的情况进行处理的
我之前是在下面这个网站进行手动转换的: https://www.upyun.com/webp
还有一些其他的工具(智图、isparta),当然我们也可以借助google的官方工具。
function checkWebp() {
try{
return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);
}catch(err) {
return false;
}
}
console.log(checkWebp());
// check_webp_feature:
// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
// 'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)
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];
}
这里提供了几种webp的图片模式,如果浏览器支持webp,那么图片的宽高会大于0,从而返回true,否则返回false.
使用方法:
第一个参数feature可以传 lossy,lossless,alpha,animation中的一个,第一个传个回调函数。获取他result。如果支持,返回ture,否则返回false。可以再谷歌和IE下试试,谷歌返回ture,IE返回false
check_webp_feature('lossless',function(feature,result){
alert(result); //true or false
});
;(function(doc) {
// 给html根节点加上webps类名
function addRootTag() {
doc.documentElement.className += "webps";
}
// 判断是否有webps=A这个cookie
if (!/(^|;\s?)webps=A/.test(document.cookie)) {
var image = new Image();
// 图片加载完成时候的操作
image.onload = function() {
// 图片加载成功且宽度为1,那么就代表支持webp了,因为这张base64图是webp格式。如果不支持会触发image.error方法
if (image.width == 1) {
// html根节点添加class,并且埋入cookie
addRootTag();
document.cookie = "webps=A; max-age=31536000; domain=58.com";
}
};
// 一张支持alpha透明度的webp的图片,使用base64编码
image.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==';
} else {
addRootTag();
}
}(document));
因为之前的项目需要用到的图片不是很多,所以我就采用了最傻瓜也是最直接的使用方法,在类中多写一个webp格式的背景图样式: 这样的写法,对于兼容webp的浏览器,会引用下方的webp背景图,对于不兼容的,则显示上方jpg格式的图片。不会因为兼容问题导致图片不显示。
不过这种方法不够灵活,只针对项目中出现少数大图需要处理时使用。减少其他配置所浪费的时间。
可以看到下面两个图的对比,使用了webp的图片响应速度还是快乐不少的。
如果项目使用了scss,也可以编辑一个函数类:
@mixin bg($url) {
background-image: url($url);
@at-root(with: all) .webps & {
background-image: url($url + '.webp');
}
}
应用之后,效果等同于:
.testbg{
background-image: url(.../test.png);
}
.webps .testbg{
background-image: url(.../test.webp);
}
可以配合上面webp格式转换的第三种方法使用。
可以借助一些其他工具,进行一些自动化的操作。当然这种适合项目中会有大量图片的情况。目前遇到的情况用上一种方法是比较简单方便且快速的。
关于webp的高级使用,后续有时间在进行补充。大家也可以网上搜索,应该会有不少文章介绍。
总之,webp在进行较大图片的替换方案上,是可以作为一种解决选择的。不过由于它的兼容性着实还不是很好。所以想要大规模系统的使用还需继续观望并期待它之后的发展。
21 May 2019