1、使用响应式图片响应式图片的优点是浏览器能够根据屏幕的大小,设备像素比ppi、横竖屏自动加载合适的图片,如使用srcset:
<img srcset="pic_w350.jpg 1x, pic_w640.jpg 2x" src="pic_w350.jpg" alt="">
屏幕的ppi=1加载1倍的图,ppi=2加载2倍图,手机和mac基本上ppi都达到2以上,这样对于普通屏幕不会浪费流量,对于视网膜又有高清的体验,如果不支持srcset,就默认加载src的图。
mac上回先加载srcset,后加载src,加载两张图,解决方法
(1)而使用picture就不会加载两张:
<picture>
<source srcset="banner_w1000.jpg" media="(min-width: 801px)">
<source srcset="banner_w800.jpg" media="(max-width: 800px)">
<img src="banner_w800.jpg" alt="">
picture>
(2)js 判断
picture必须要写img标签,否则无法显示
var supportSrcset = 'srcset' in document.createElement('img');
var surportPicture = 'HTMLPictureElement' in window;
图片格式兼容处理:
webp在保持同等清晰度的情况下,体积可以减少一半,但是目前只有Chrome支持,Safari和firefox一直处于实验阶段,所以其它的浏览器如firefox将会加载jpg格式的照片:
<picture>
<source type="image/webp" srcset="banner.webp">
<img src="banner.jpg" alt="">
picture>
2、延迟加载图片
许多网站,图片往往是占据最多流量和带宽的的资源。特别是那种瀑布式展示性的网站,几十张图片,如果一口气全部放出来,那么页面的Loaded时间将会较长,并且由于并行加载资源数是有限,图片太多会导致放body后面的js解析比较慢,页面将较长时间处于不可交互状态。
所以不能一下子把全部图片都放出来,这对于手机上的流量也是不利的。
解决方法:
懒惰加载图片:初始不加载图片,只当用户下滑到相应位置时候才放图片出来。
(1)初始是不把图片放在src,而是放在data里面,
<picture>
<source data-srcset="photo_w350.jpg 1x, photo_w640.jpg 2x">
<img data-src="photo_w350.jpg" src="about:blank" alt="">
picture>
(2)监听scroll事件,回调函数
第5行for循环,依次对所有的图片做处理,第8行的if判断,如果滑动的位置快要到那张图片了,则把src放出来,这个位置差默认为500px,如果图片加载得快的话,这种行为对于用户来说是透明的,他可能不知道图片是往下滑的时候才放出来的,几乎不会影响体验,如果用户滑得很快,本身不做这样的处理,也不可能加载得这么快,也是loading的状态。
showImage(leftSpace = 500){
var scrollTop = $window.scrollTop();
var $containers = this.$imgContainers,
for(var i = 0; i < $containers.length; i++){
//如果快要滑到图片的位置了
var $container = $containers.eq(i);
if($container.offset().top - scrollPosition < leftSpace){
this.ensureImgSrc($container);
}
}
}
(3)下面的函数把图片放出来
代码里面判断src是不是有”//”,即为正常的地址,如果没有给它赋值,触发浏览器加载图片。
ensureImgSrc($container){
var $source = $container.find("source");
if($source.length && !$source.attr("srcset")){
$source.attr("srcset", $source.data("srcset"));
}
var $img = $container.find("img:not(.loading)");
if($img.length && $img.attr("src").indexOf("//") < 0){
$img.attr("src", $img.data("src"));
this.shownCount++;
}
}
并记录已经放出来的个数,这样可以做个优化,当图片全部都加载或者开始加载了,把scroll事件取消掉:
init(){
//初始化
var leftSpace = 0;
this.showImage(leftSpace);
//滑动
$window.on("scroll", this, this.throttleShow);
}
ensureImgSrc($container){
//如果全部显示,off掉window.scroll
if(this.shownCount >= this.allCount){
$window.off("scroll", this.throttleShow);
}
}
这样可以大大减少打开页面的流量,加快ready和load的时间。