作为网页内容的一部分,图像和视频通常要消耗很多资源加载。要提高网页应用的性能,如何避免资源浪费在加载图像和视频上就很重要了。但是,很多时候我们都不愿意减少网页上的媒体资源,所以我们经常无从下手。幸运的是,我们有懒加载这个绝招,它可以帮助我们减少加载时间和降低负载,而不在内容上偷工减料。
1.懒加载工作原理
通俗点讲,就是在页面还没到达图片位置的时候不用事先加载,不作显示或者设置loading加载。只有当页面滚动条到达图片所在位置,才将真正的图片渲染到页面上去。显然,这里需要通过监听scroll滚动事件实现懒加载效果。
2.懒加载实现方案
通过分析,我们需要知道两个高度:窗口显示区的高度和图片到视窗上边的距离高度。
图片未能看见:图片距离视窗顶部的距离 > 窗口显示区的高度。
图片能看见:图片距离视窗顶部的距离 < 窗口显示区的高度。
首先,可以给图片设置一个自定义属性data-src,默认src属性则设置为loading加载图片或者为空。其中 data- 为自定义属性,通常情况下,浏览器不会执行自定义属性。之后,添加滚动监听事件,将img的自定义属性data-src赋值给默认属性src。
3.核心js代码
注意:使用offsetTop和scrollTop的时候一定要保证当前页面元素已全部被渲染。
// 获取所有img的dom元素 并全部设置为loading加载图片 let imgs = document.querySelectorAll('img'); imgs.forEach(img => { img.src = './loading.gif'; }) // 懒加载函数 const lazyload = () => { imgs.forEach(img => { //图片距离顶部的距离 包含卷上去的部分 let imgoffsettop = img.offsetTop; // 页面被卷去的高度 let scrollT = document.documentElement.scrollTop; //浏览器可视区的高度 let view = window.innerHeight; // 图片到视窗上边的距离高度 < 窗口显示区的高度 ,这时候,才需要加载 if (imgoffsettop - scrollT < view) { //设置一个定时器 目的是为了让懒加载的效果更明显 setTimeout(() => { img.src = img.dataset.src }, 800); } }) } // onload保证页面元素已全部渲染 window.onload = function() { //进入页面 初始化执行 lazyload(); //滚动执行 window.addEventListener('scroll', lazyload); }
4.html代码
示例代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <img data-src="https://img0.baidu.com/it/u=128726096,3499341032&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=698"></img> <img data-src="https://img1.baidu.com/it/u=2944608286,2060518702&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=727"></img> <div></div> <img data-src="https://img2.baidu.com/it/u=3274749659,1709808198&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"></img> <img data-src="https://img2.baidu.com/it/u=2357389186,1982056366&fm=253&fmt=auto&app=120&f=JPEG?w=640&h=960"></img> <div></div> <img data-src="https://img2.baidu.com/it/u=3711757854,2517951413&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=700"></img> <img data-src="https://img2.baidu.com/it/u=3532455937,1503056366&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=1422"></img> <div></div> <img data-src="https://img2.baidu.com/it/u=4192422414,1862812180&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"> <img data-src="https://img1.baidu.com/it/u=4069446031,1929672719&fm=253&fmt=auto&app=138&f=JPEG?w=333&h=500"> <div></div> <img data-src="https://img1.baidu.com/it/u=1846905306,2792027856&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=779"> <img data-src="https://img0.baidu.com/it/u=1993836752,2372618051&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889"> <div></div> <img data-src="https://img1.baidu.com/it/u=4216615779,3871708882&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889"> <img data-src="https://img2.baidu.com/it/u=109659060,2014363234&fm=253&fmt=auto&app=138&f=JPEG?w=334&h=500"> <div></div> <img data-src="https://img2.baidu.com/it/u=2991838151,1877228912&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=888"> <img data-src="https://img0.baidu.com/it/u=642326292,3709733592&fm=253&fmt=auto&app=138&f=JPEG?w=346&h=500"> <style> img { height: 300px; width: 230px; } /* div的目的仅仅是为了撑开图片之间的上下距离 更好的模拟业务场景 */ div { height: 200px; } </style> </body> </html>