作为网页内容的一部分,图像和视频通常要消耗很多资源加载。要提高网页应用的性能,如何避免资源浪费在加载图像和视频上就很重要了。但是,很多时候我们都不愿意减少网页上的媒体资源,所以我们经常无从下手。幸运的是,我们有懒加载这个绝招,它可以帮助我们减少加载时间和降低负载,而不在内容上偷工减料。

1.懒加载工作原理

通俗点讲,就是在页面还没到达图片位置的时候不用事先加载,不作显示或者设置loading加载。只有当页面滚动条到达图片所在位置,才将真正的图片渲染到页面上去。显然,这里需要通过监听scroll滚动事件实现懒加载效果。

2.懒加载实现方案

通过分析,我们需要知道两个高度:窗口显示区的高度和图片到视窗上边的距离高度。
图片未能看见:图片距离视窗顶部的距离 > 窗口显示区的高度。
图片能看见:图片距离视窗顶部的距离 < 窗口显示区的高度。

首先,可以给图片设置一个自定义属性data-src,默认src属性则设置为loading加载图片或者为空。其中 data- 为自定义属性,通常情况下,浏览器不会执行自定义属性。之后,添加滚动监听事件,将img的自定义属性data-src赋值给默认属性src。


3.核心js代码

注意:使用offsetTop和scrollTop的时候一定要保证当前页面元素已全部被渲染。

复制代码
  1. // 获取所有img的dom元素 并全部设置为loading加载图片
  2. let imgs = document.querySelectorAll('img');
  3. imgs.forEach(img => {
  4. img.src = './loading.gif';
  5. })
  6. // 懒加载函数
  7. const lazyload = () => {
  8. imgs.forEach(img => {
  9. //图片距离顶部的距离 包含卷上去的部分
  10. let imgoffsettop = img.offsetTop;
  11. // 页面被卷去的高度
  12. let scrollT = document.documentElement.scrollTop;
  13. //浏览器可视区的高度
  14. let view = window.innerHeight;
  15. // 图片到视窗上边的距离高度 < 窗口显示区的高度 ,这时候,才需要加载
  16. if (imgoffsettop - scrollT < view) {
  17. //设置一个定时器 目的是为了让懒加载的效果更明显
  18. setTimeout(() => {
  19. img.src = img.dataset.src
  20. }, 800);
  21. }
  22. })
  23. }
  24. // onload保证页面元素已全部渲染
  25. window.onload = function() {
  26. //进入页面 初始化执行
  27. lazyload();
  28. //滚动执行
  29. window.addEventListener('scroll', lazyload);
  30. }


4.html代码

示例代码:

复制代码
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <img
  9. data-src="https://img0.baidu.com/it/u=128726096,3499341032&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=698"></img>
  10. <img
  11. data-src="https://img1.baidu.com/it/u=2944608286,2060518702&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=727"></img>
  12. <div></div>
  13. <img
  14. data-src="https://img2.baidu.com/it/u=3274749659,1709808198&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"></img>
  15. <img
  16. data-src="https://img2.baidu.com/it/u=2357389186,1982056366&fm=253&fmt=auto&app=120&f=JPEG?w=640&h=960"></img>
  17. <div></div>
  18. <img
  19. data-src="https://img2.baidu.com/it/u=3711757854,2517951413&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=700"></img>
  20. <img
  21. data-src="https://img2.baidu.com/it/u=3532455937,1503056366&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=1422"></img>
  22. <div></div>
  23. <img data-src="https://img2.baidu.com/it/u=4192422414,1862812180&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750">
  24. <img data-src="https://img1.baidu.com/it/u=4069446031,1929672719&fm=253&fmt=auto&app=138&f=JPEG?w=333&h=500">
  25. <div></div>
  26. <img data-src="https://img1.baidu.com/it/u=1846905306,2792027856&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=779">
  27. <img data-src="https://img0.baidu.com/it/u=1993836752,2372618051&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889">
  28. <div></div>
  29. <img data-src="https://img1.baidu.com/it/u=4216615779,3871708882&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889">
  30. <img data-src="https://img2.baidu.com/it/u=109659060,2014363234&fm=253&fmt=auto&app=138&f=JPEG?w=334&h=500">
  31. <div></div>
  32. <img data-src="https://img2.baidu.com/it/u=2991838151,1877228912&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=888">
  33. <img data-src="https://img0.baidu.com/it/u=642326292,3709733592&fm=253&fmt=auto&app=138&f=JPEG?w=346&h=500">
  34. <style>
  35. img {
  36. height: 300px;
  37. width: 230px;
  38. }
  39. /* div的目的仅仅是为了撑开图片之间的上下距离 更好的模拟业务场景 */
  40. div {
  41. height: 200px;
  42. }
  43. </style>
  44. </body>
  45. </html>