乐趣区

关于vue.js:懒加载预加载

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
退出移动版