前言
一般来说,影响一个网站加载时间的最大因素就是图片资源过多。一般的网页大小只有几十 k,而图片资源往往可能达到几 M。 有关于图片加载机制的可以看 。所以对于图片很多的页面,为了加速页面加载速度,我们一般需要对图片资源进行懒加载。
懒加载:顾名思义就是延迟加载的意思。当图片在窗口不可见的范围内不加载,滚动到可视区域之后再进行加载。
原理
img
标签在没有 src
属性时是不会加载图片资源的(注:src
属性只有存在就会向服务器发送请求),这里我们还需要用到data-src
这个属性来存储图片地址。当图片滚动到可视区域时,将data-src
的值赋给src
。当然,常用做法也可能用一张默认的图来进行占位 <img src='/assets/imgs/default.png' data-src='https://meizi.yitianyibu.cn/meizi.jpg'>
。
实现
懒加载 复制代码
代码部分来源于
var imgsCount = document.getElementsByTagName("img").length;var imgs = document.getElementsByTagName("img");var count = 0; //存储图片加载到的位置,避免每次都从第一张图片开始遍历lazyload(); //页面载入完毕加载可是区域内的图片window.onscroll = lazyload;function lazyload() { //监听页面滚动事件 var seeHeight = document.documentElement.clientHeight; //可见区域高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度 for (var i = count; i < imgsCount; i++) { if (imgs[i].offsetTop < seeHeight + scrollTop) { if (imgs[i].getAttribute("src") == "default.jpg") { imgs[i].src = imgs[i].getAttribute("data-src"); } count = i + 1; } }}复制代码
节流优化
从上面代码来看,lazyload
函数是绑定在window.onscroll
上的。当页面滚动时,lazyload
会不断的调用,会非常影响浏览器性能。所以我们需要对lazyload
函数做节流(throttle
)
这是underscore
节流函数实现
function throttle(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : new Date().getTime(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; return function() { var now = new Date().getTime(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; };}复制代码
结合节流函数
window.addEventListener("scroll", throttle(lazyload, 500));复制代码
其他实现
查了一下资料IntersectionObserver
这个api也可以实现懒加载