懒加载js实现和优化

Posted Ambition

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了懒加载js实现和优化相关的知识,希望对你有一定的参考价值。

1.懒加载的作用和原理

  在我们展示多图片的场景下,类似淘宝或者百度图片,由于图片的数目过多,全部从服务器请求会给用户糟糕的用户体验,为了提升用户体验,我们这里使用懒加载,随着下拉逐步加载。

  每个图片的src会有一个get请求,我们把不能看到的图片src设置为相同的图片,这些图片发一次请求即可,设置属性data-src为真正的图片路径。当图片滚动到可视区,我们就用js把data-src 赋值给 src,简单的懒加载就可以实现了。

2.简单的js实现懒加载

 //你需要一张timg.png图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        img{
            display: block;
            width: 700px;
            height: 400px;
        }
    </style>
</head>
<body>
    <ul class="img-group">
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158197&di=8845befd9fbda1e99e565b9c2298be50&imgtype=0&src=http%3A%2F%2Fuploads.xuexila.com%2Fallimg%2F1503%2F626-15031G42255b3.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158196&di=4a38d248001c145c5b4dd31474dedf41&imgtype=0&src=http%3A%2F%2Fpic29.nipic.com%2F20130512%2F11178195_152908769116_2.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158196&di=b39e8b14d214b7aa518d7a8328939efb&imgtype=0&src=http%3A%2F%2Fimage16-c.poco.cn%2Fmypoco%2Fmyphoto%2F20141114%2F12%2F4567377520141114124637053.jpg%3F1024x684_120"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158196&di=f2e7a6ffbfa3f92025c91e6180b5e317&imgtype=0&src=http%3A%2F%2Ffile31.mafengwo.net%2FM00%2F3F%2F26%2FwKgBs1gXBQuAPWGGABOK4vbGpt412.groupinfo.w600.jpeg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158195&di=6a073a070b9cea1214efc0994ed6dde1&imgtype=0&src=http%3A%2F%2Fimages3.ctrip.com%2Fwri%2Fimages%2F200610%2F100602312604121954734.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158195&di=a9436d83f55b301d1df9cd24f6e367e7&imgtype=0&src=http%3A%2F%2Fcyjctrip.qiniudn.com%2F69015%2F1379755311203p184vt4juft5p1t8q1andgp5ijn11.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158195&di=2b6bc6b871d4f7f267169dfcfb727f84&imgtype=0&src=http%3A%2F%2Fcyjctrip.qiniudn.com%2F106357%2F1395933091608p18k21ek6kvj1gv2ta910kn1002m.jpg"></li>
    </ul>
<script type="text/javascript">
        let imgArr = document.querySelectorAll(\'img\');
        let len = imgArr.length;
        window.onscroll = function () {
            let seeHeight = document.documentElement.clientHeight;
            console.log("seeHeight ="+seeHeight);
            let scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            console.log("scrollTop ="+scrollTop);
            for(let i=0; i<len; i++){
                console.log(imgArr[i].offsetTop);
                if(imgArr[i].offsetTop < seeHeight + scrollTop){
                        if(imgArr[i].getAttribute(\'src\')==\'timg.jpg\'){
                            imgArr[i].src = imgArr[i].getAttribute(\'data-src\');
                        }
                }
            }
        }
</script>
</body>
</html>

 

 我们根据js代码分析一下,主要有两部分

1>.如何加载图片? 

   img.src  = img.getAttribute(\'data-src\');

2>.如何判断是否在可视区

    就是 图片的 offsetTop <  scrollTop + clientHeigth 即可

  

 

 

 好了上面就是我们简单的js实现和原理,但是看到各位大佬提到这里有三个需要优化的地方。

1.在初始条件下,应该有图片显示,只要在加载完毕之后滚动之前执行图片的加载即可

2.函数节流,但我们在高频度的滚动时,每隔一段事件开始图片的渲染。实现原理是 加入一个开关变量, 控制每隔固定的一段时间,函数才可能被触发

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        img{
            display: block;
            width: 700px;
            height: 400px;
        }
    </style>
</head>
<body>
    <ul class="img-group">
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158197&di=8845befd9fbda1e99e565b9c2298be50&imgtype=0&src=http%3A%2F%2Fuploads.xuexila.com%2Fallimg%2F1503%2F626-15031G42255b3.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158196&di=4a38d248001c145c5b4dd31474dedf41&imgtype=0&src=http%3A%2F%2Fpic29.nipic.com%2F20130512%2F11178195_152908769116_2.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158196&di=b39e8b14d214b7aa518d7a8328939efb&imgtype=0&src=http%3A%2F%2Fimage16-c.poco.cn%2Fmypoco%2Fmyphoto%2F20141114%2F12%2F4567377520141114124637053.jpg%3F1024x684_120"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158196&di=f2e7a6ffbfa3f92025c91e6180b5e317&imgtype=0&src=http%3A%2F%2Ffile31.mafengwo.net%2FM00%2F3F%2F26%2FwKgBs1gXBQuAPWGGABOK4vbGpt412.groupinfo.w600.jpeg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158195&di=6a073a070b9cea1214efc0994ed6dde1&imgtype=0&src=http%3A%2F%2Fimages3.ctrip.com%2Fwri%2Fimages%2F200610%2F100602312604121954734.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158195&di=a9436d83f55b301d1df9cd24f6e367e7&imgtype=0&src=http%3A%2F%2Fcyjctrip.qiniudn.com%2F69015%2F1379755311203p184vt4juft5p1t8q1andgp5ijn11.jpg"></li>
        <li><img src="timg.jpg" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497274158195&di=2b6bc6b871d4f7f267169dfcfb727f84&imgtype=0&src=http%3A%2F%2Fcyjctrip.qiniudn.com%2F106357%2F1395933091608p18k21ek6kvj1gv2ta910kn1002m.jpg"></li>
    </ul>
<script type="text/javascript">
        let imgArr = document.querySelectorAll(\'img\');
        let len = imgArr.length;
        let n = 0; //记录加载图片的位置,避免从第一张开始加载
        let canrun = true;
        let seeHeight = document.documentElement.clientHeight;
        console.log("seeHeight ="+seeHeight);

        lazyLoad();
        window.onscroll = function () {
            if(!canrun){
                return ;
            }
            canrun = false;
            setTimeout(function () {
                console.log(\'*****\');
                lazyLoad();
                canrun= true;
            },1000);

        }

        function lazyLoad() {
            let scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            console.log("scrollTop ="+scrollTop);
            for(let i=0; i<len; i++){
                console.log(imgArr[i].offsetTop);
                if(imgArr[i].offsetTop < seeHeight + scrollTop){
                    if(imgArr[i].getAttribute(\'src\')==\'timg.jpg\'){
                        imgArr[i].src = imgArr[i].getAttribute(\'data-src\');
                    }
                    n = i+1;
                    console.log("n="+n);
                }
            }
        }
</script>
</body>
</html>

 

这是以上的两个优化之后的代码。

 

以上是关于懒加载js实现和优化的主要内容,如果未能解决你的问题,请参考以下文章

原生js实现图片列表懒加载和截流

懒加载和预加载---性能优化

页面性能优化-原生JS实现图片懒加载

vue-router和webpack懒加载,页面性能优化篇

vuevue-cli3构建项目中实现图片懒加载

webpack性能优化:分隔/分包/异步加载+组件与路由懒加载