图片懒加载原理

2,716 阅读2分钟

背景

懒加载是前端重要的优化手段,尤其是对图片而言,因为非常耗资源。所以我们来了解一下原理吧~

github地址在此

准备

  • img标签的src会触发http请求,是一种通过浏览器的外部资源加载的表现,同时还有script标签等(同时可应用于jsonp)
  • 图片距离顶部高度:el.offsetTop
  • 视窗高度:window.innerHeight
  • 滚动条滚动的高度:el.scrollTop(el是滚动条所在的元素,有可能是body)

开始

创建所有图片

这里为了方便,就用div模拟了。innerTxet替换了就相当于img标签的src被替换了。

let imgArr = Array(100).fill('image')
let images = document.getElementsByClassName('img')
let app = document.getElementById('app')
imgArr.forEach((item) => {
    let div = document.createElement('div')
    div.classList = 'load img'
    div.innerText = '尚未出现在视窗(我是默认图片)'
    app.appendChild(div)
})

现实中,也是一样的。我们会把没有出现在视窗内的图片,用一张占位符图片来代替。

初始化图片状态(在视窗内和不在视窗内)

let windowHeight = window.innerHeight
function mountedImg() {
    for (let i = 0; i < images.length; i++) {
        let imgHeight = images[i].offsetTop
        if (imgHeight < windowHeight) {
            setTimeout(() => {
                images[i].innerText = '出现在视窗(这是正确的图片)'
            }, 500)
        }
    }
}
//初始化
mountedImg()

这里就初始化在视窗内的图片,就是占位符图片赋予正确的src。

滚动懒加载

监听滚动事件,同时考虑节流~

//节流函数,在一定时间内不触发该函数
function throttle() {
    //守卫标志
    let canRun = true
    return function () {
        if (canRun) {
            canRun = false
            let scrollTop = document.documentElement.scrollTop
            //懒加载
            for (let i = 0; i < images.length; i++) {
                let imgHeight = images[i].offsetTop
                if (imgHeight < scrollTop + windowHeight) {
                    images[i].innerText = '出现在视窗(这是正确的图片)'
                }
            }
            //1s后守卫正常
            setTimeout(() => {
                canRun = true
            }, 1000)
        }
    }
}

节流函数就像是游戏中的cd,一段时间你再怎么按都触发不了,要等过了这个cd(联想一下王者荣耀),你的大招节流了,不能无限按!