WEB性能优化--图片媒体篇

目标为了晋升客户端成果体验。

原生js实现(懒加载)

  • 原理:图片的getBoundingClientRect().top高度 是否小于以后可视视图高度,小于则把data-src的url替换给src

1、第一种办法:获取对应元素举例顶部的间隔来判断。

// onload是等所有的资源文件加载结束当前再绑定事件window.onload = function(){    // 获取图片列表,即img标签列表    var imgs = document.querySelectorAll('img');    // 获取到浏览器顶部的间隔    function getTop(e){        return e.getBoundingClientRect().top;    }    // 懒加载实现    function lazyload(imgs){        // 可视区域高度        var h = window.innerHeight;        //滚动区域高度                for(var i=0;i<imgs.length;i++){            //图片间隔顶部的间隔大于可视区域和滚动区域之和时懒加载            if (h>getTop(imgs[i])) {                // 真实情况是页面开始有2秒空白,所以应用setTimeout定时2s                (function(i){                    setTimeout(function(){                        // 不加立刻执行函数i会等于9                        // 隐形加载图片或其余资源,                        //创立一个长期图片,这个图片在内存中不会到页面下来。实现隐形加载                        var temp = new Image();                        temp.src = imgs[i].getAttribute('data-src');//只会申请一次                        // onload判断图片加载结束,真是图片加载结束,再赋值给dom节点                        temp.onload = function(){                            // 获取自定义属性data-src,用真图片替换假图片                            imgs[i].src = imgs[i].getAttribute('data-src')                        }                    },2000)                })(i)            }        }    }    lazyload(imgs);    // 滚屏函数    window.onscroll =function(){        lazyload(imgs);    }}

2、第二种办法:利用intersectionObserver-api监听元素是否进入到可视区域(较第一种办法更简略)

// 利用es6写法    const imgsBox = [...document.querySelectorAll('img')];        function lazyload(){        for(let i = 0;i<imgsBox.length;i++){            const imgsTarget = imgsBox[I];            if(isVisable(imgsTarget)){                imgsTarget.src = imgsTarget.dataset.src;                imgsTarget.splice(i,1);//取得图片后出数组                i--;            }        }    }     //判断图片是否再可视化区域    function isVisable(imgsTarget){        let targetRect =  imgsTarget.getBoundingClientRect();                return targetRect.bottom >0 && targetRect.top < window.innerHeight && targetRect.right >0 && targetRect.left < window.innerWight;    }        lazyload();    window.onscroll = function(){        lazyload();    }        //onscroll也能够写成        window.addEventListener('scroll',lazyload,false);    //false 示意冒泡

上诉办法因为scroll是高频发事件,所以用的时候最好应用节流函数。

function throttle(fn,wait,context){    var timer = null;    return function(...args){        var context = context || this;        var args = arguments;        if(!timer){            timer = setTimeout(function(){                fn.apply(context,args);                timer = null;            },wait)        }    }}    window.addEventListener('scroll',throttle(lazyload,250),false);    

原生js(图片预加载)

  • 提前加载下一张图片,基于promise实现
    <img id='imgbox' /> const imgs = [ ]; //用来寄存图片src的数组,理论状况是去后盾取的值  const imgBox = document.getElementById('imgbox'); //取到寄存src的图片盒子,通过预加载替换src  //这里用点击图片替换图片来实现预加载  let i = 0; //用来取数组图片src imgBox.addEventListener('click', ()=>{    if(i < imgs.length){     imgBox.src = imgs[i];     i++;        if(i< imgs.length){            preLoad(imgs[i]).then(data=>{ //这个data就是咱们 return 的promise对象,传入imgs[i]的 });        }    }else{        //此时是数组最初一张图片    }      },false)     function preLoad(src){        return new Promise(reslove,reject)=>{           const imgBox = document.getElementById('imgbox');           imgBox.src = src;           imgBox.addEventerListener('load',()=>{reslove(imgBox)});           imgBox.addEventerListener('error',()=>{reject()});        }    }
借鉴学习:https://juejin.cn/post/703445...

巧用lazysizes.js 插件实现懒加载

  • 这个插件应用益处介于高频发、无论元素是否ajax实现,lazysizes都能够拾取到。
  • 下载lazysizes.min.js 脚本。(或通过 npm:npm install lazysizes --save或 bower装置bower install lazysizes --save)
  • 应用办法: 官网应用例子
  • 官网文档:github