前端性能优化:利用防抖节流实现图片懒加载

前端性能优化:利用闭包节流实现图片懒加载

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片懒加载title>
head>
<style>
    img{
        display: block;
        width: 300px;
        height: 300px;
        margin: 30px auto;
    }
style>
<body>
<h1>图片懒加载h1>
    <img data-src="./img/1.jpeg" src="">
    <img data-src="./img/2.jpeg" src="">
    <img data-src="./img/3.jpeg" src="">
    <img data-src="./img/4.jpeg" src="">
    <img data-src="./img/5.jpeg" src="">
    <img data-src="./img/6.jpeg" src="">
    <img data-src="./img/7.jpeg" src="">
    <img data-src="./img/8.jpeg" src="">
    <img data-src="./img/9.jpeg" src="">
<script>
    let img = document.getElementsByTagName('img')
    let _clientHeight = document.documentElement.clientHeight // 可见视口高度
    let _scrollTop = document.documentElement.scrollTop || document.body.scrollTop // 初始化时:滚动条距离顶部高度
    let imgLength = img.length // 图片数量
    let currentLoad = 0 // 存储图片当前加载的位置,避免每次都从第一张加载
    let isLoadImg = false // 标识当前页面/容器图片是否加载完成
    // 监听窗口变化 重新计算可视区域
    function computedClientHeight() {
        _clientHeight = document.documentElement.clientHeight // 可见视口高度
        console.log('_clientHeight',_clientHeight)
    }
    function lazyLoad() {
        isLoadImg = currentLoad >= imgLength
        console.log('isLoadImg',isLoadImg)
        if (!isLoadImg){// 图片未全部加载时执行
            console.log('执行懒加载')
            _scrollTop = document.documentElement.scrollTop || document.body.scrollTop // 后续获取:滚动条距离顶部高度
            for (let i = currentLoad;i<imgLength;i++){
                if (img[i].offsetTop<_clientHeight+_scrollTop){ //图片距离文档流顶部的距离<视口距离+视口距离文档流顶部偏移的距离
                    if (img[i].getAttribute('src') ===''){
                        img[i].src = img[i].getAttribute('data-src')
                    }
                    currentLoad = i+1 //当前加载图片+1
                }
            }
        }
    }
    lazyLoad();//初始化执行,显示初始化图片
    /**
     * 节流函数
     * @param func 回调函数
     * @param wait 等待下次触发的时间
     */
    function throttle(func,wait){
        let timer
        return ()=>{
                if (isLoadImg){// 图片加载完成,不在执行节流
                    return
                }
                if (!timer){// 不存在延时器 时执行
                    console.log('执行节流')
                    timer = setTimeout(()=>{
                        func()
                        //清除当前执行的定时器
                        clearTimeout(timer)
                        timer = null
                    },wait)
                }
        }
    }
    /**
     * 防抖函数
     * @param delay 延时时间
     * @param value 传入值
     */
    function debounce(callback,delay) {
        let timer
        return (value=null)=>{
            clearTimeout(timer)
            if (isLoadImg){ //图片加载完成,不在执行防抖函数
                return
            }
            // 需要清除的timer,利用闭包将timer一直保存在内存之中
            timer = setTimeout(()=>{
                console.log('防抖执行')
                // console.log(value) // 若结果不再此处输出
                callback(value);
            },delay)
        }
    }
    // 节流实现性能较好的懒加载, 原本多次触发的scroll事件,现在一定时间内只触发一次
    window.addEventListener('scroll',throttle(lazyLoad,100))
    // 防抖是优化不断触发的窗口变化,只在窗口不在变化时计算最的终值
    window.addEventListener('resize',debounce(computedClientHeight,800))
script>
body>
html>

你可能感兴趣的:(#,前端性能优化,前端,javascript)