图片懒加载

我心飞翔 分类:javascript

前言

图片的懒加载一直都是大厂热门的考题,可为什么他能成为大厂们纷纷趋之若鹜的香馍馍呢,这就要提到它的好处了——性能优化,对就是性能优化,要知道,所有的产品最终是要服务于客户的,而谁能使客户的体验感更好,谁就能笑到最后,而性能就是其中最重要的一环。

什么是图片懒加载?

懒加载突出一个“懒”字,懒就是拖延迟的意思,所以“懒加载”说白了就是延迟加载,比如我们加载一个页面,这个页面很长很长,长到我们的浏览器可视区域装不下,那么懒加载就是优先加载可视区域的内容,其他部分等进入了可视区域在加载。

为什么要图片懒加载?

懒加载是一种网页性能优化的方式,它能极大的提升用户体验。就比如说图片,图片一直是影响网页性能的主要元凶,现在一张图片超过几兆已经是很经常的事了。如果每次进入页面就请求所有的图片资源,那么可能等图片加载出来用户也早就走了。所以,我们需要懒加载,进入页面的时候,只请求可视区域的图片资源。

原理

图片懒加载,那我们要实现懒加载,当然是要对图片下手啦!

大家都知道,一张图片就是一个标签,而图片的来源主要是src属性。浏览器是否发起亲求就是根据是否有src属性决定的。

既然这样,那么我们就要对标签的src属性下手了,在没进入可视区域的时候,我们先不给这个标签赋src属性,这样岂不是浏览器就不会发送请求了。

实现

1.先介绍几个和懒加载相关的API

  • 浏览器窗口的视口(viewport)高度(以像素为单位);如果有水平滚动条,也包括滚动条高度。

var intViewportHeight = window.innerHeight;

  • Element.clientHeight没有CSS或内联布局框的元素的只读属性为零;否则,它是元素的内部高度(以像素为单位)。它包括填充,但不包括边框,边距和水平滚动条(如果存在)。

document.documentElement.clientHeight//获取屏幕可视区域的高度

好啦好啦,讲道理千遍万遍,不如过一遍代码,我们上代码!

与普通的图片懒加载不同,如下这个多做了 2 个精心处理:

  • 图片全部加载完成后移除事件监听;
  • 加载完的图片,从 imgList 移除;
let imgList = [...document.querySelectorAll('img')]
let length = imgList.length
// 把图片查询分配到一个数组
const imgLazyLoad = function() {
    let count = 0
   return (function() {
        let deleteIndexList = []
        imgList.forEach((img, index) => {
            let rect = img.getBoundingClientRect()
            if (rect.top < window.innerHeight) {
                img.src = img.dataset.src
                deleteIndexList.push(index)
                count++
                if (count === length) {
                    document.removeEventListener('scroll', imgLazyLoad)
                }
            }
        })
        imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
   })()
}

// 这里最好加上防抖处理
document.addEventListener('scroll', imgLazyLoad)

 

其实吧,这个代码对于你们这些大佬来说,挺简单的,但是对于我这种小菜鸡来说,还是有点困难的,所以我还是简单讲一下几个点呗,夯实一下我自己的学习,所以大佬们多多担待,多谢多谢!

  1. return (function() {}) 这其实就是一个自执行函数的实现。

而什么是自执行函数呢?

自行调用的函数: 就是指,函数在页面载入后或者之前就自行调用,无需借助其他函数或方法来启动;

  1. img.getBoundingClientRect() 咳咳,我想你们都把这个这么长的东东都在脑海里读了一遍吧!嘿嘿,我就没有。

那言归正传,这个东西到底是啥呢?我们看到前面加了一个img.那我我们肯定知道它和图片有关,那么我们来解释一下呗:

img.getBoundingClientRect()就是图片到视窗viewport的上或者左边的距离,它有四个属性

  • top 图片上边距离视窗上边的距离
  • bottom 图片下边距离视窗上边的距离
  • left 图片左边距离视窗左边的距离
  • right 图片右边距离视窗左边的距离

这样说,是不是有点模糊呢? 所以说,我是个好人,精心为你们“偷”了张图片过来,看了下面那张图,你就全懂了。

element-box-diagram.png

  1. document.removeEventListener('scroll', imgLazyLoad) 这里呢,就是图片全部加载完成后移除事件监听,那它这样干的理由是什么呢?

没错,就是防抖处理

简而言之就是,通过移除监听事件来实现防抖处理。

而,关于防抖,我就简单说一下,不做过多解释,我的下篇文章会讲。什么?你问下篇文章在哪?额。。。,我只能告诉你,等几天!

防抖:防止抖动,以免把一次事件误执行多次,影响性能,比如敲键盘就是一个每天都会接触到的防抖操作。
4. !deleteIndexList.includes(index)

  • includes() 方法用于判断字符串是否包含指定的子字符串。

    如果找到匹配的字符串则返回 true,否则返回 false。

注意: includes() 方法区分大小写。

  • 我想很多同学都对这个!deleteIndexListincludes(index)有点莫名其妙吧,那我们来解析一下呗!
  1. 首先,deleteIndexList.includes(index)是一个方法,没错吧!它就是查询deleteIndexList数组里是否含有指定的index如果有,我们就返回ture否则就返回false.
  2. 那前面再加上!是啥意思呢,我们都知道!有取反的意思,所以在方法前面加上!就是对于方法的返回值取反。

总结:
所以这句代码的作用就是删除imgLIst里面加载完的图片。

总结

好了好了,介绍也介绍的差不多了,剩下的相信以小伙伴们的实例,解决它就是洒洒水的事情,所以我们到这里就结束咯,小伙伴们加油加油!拜拜

回复

我来回复
  • 暂无回复内容