前端性能优化-图片懒加载(防抖、节流)

懒加载使用场景

在一些图片量比较大的场景(电商首页,小程序首页等),如果我们打开页面时就加载所有的图片,那势必会导致页面的卡顿以及白屏,给用户不好的体验,导致用户流失。

但是我们仔细想一下,用户真的需要我们显示所有图片一起展示吗?其实并不是,用户看到的只是浏览器可视区域的内容。所以从这个情况我们可以做一些优化,只显示用户可视区域内的图片,当用户触发滚动的瞬间再去请求显示给用户。

懒加载的思路

  • img 标签有自定义属性 data-src
  • 首屏展示可视区域内的图片 src 值 替换为 data-src
  • 滚动出现在可视区域的图片即时展示 (重复第二步)

懒加载的实现

<style>
    html,
    body {
        width: 100%;
        height: 100%;
    }

    .containr {
        width: 100%;
        height: 100%;
        overflow-y: auto;

    }

    .img {
        width: 100%;
        height: 300px;
    }

    .pic {
        width: 100%;
        height: 300px;
    }
</style>

<div class="containr">
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/1.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/2.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/3.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/4.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/5.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/6.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/7.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/8.png">
        </div>
        <div class="img">
            <img class="pic" src="" alt="" data-src="./imgs/9.png">
        </div>

</div>
    
<script>
        // 获取所有图片的数组
        const imgs = document.querySelectorAll('.containr .pic')
        // 获取父元素
        const containr = document.querySelector('.containr')
        // 获取可视区域高度
        const viewHeight = window.innerHeight
        
        const load = lazyLoad()
        // 首屏渲染
        load()
        function lazyLoad() {
            // 运用闭包 count 进行计数 避免已显示的图片重复参与循环
            let count = 0
            return () => {
                for (let i = count; i < imgs.length; i++) {
                    // getBoundingClientRect()获取返回元素的大小及其相对于视口的位置
                    // 获取第i张图片是否在可视区域
                    let distance = viewHeight - imgs[i].getBoundingClientRect().top
                    if (distance >= 0) {
                        // 图片在可视区域时设置图片的src 为 当前元素 data-src
                        imgs[i].src = imgs[i].getAttribute('data-src')
                        // 图片已被显示,下次从count + 1 张开始检查是否在可视区域
                        count += 1
                    }
                }
            }
        }
        // 添加滚动事件触发加载
        containr.addEventListener('scroll', load, false)

</script>

至此我们已经初步完成了我们的懒加载,但是我们大家都知道,scroll这个事件实在太容易被触发了,用户一滚动鼠标就会触发很多次,如果一直滚势必会导致重复触发执行我们的事件,这也会导致我们的性能急剧下降,所以这就引出了我们的混合体 防抖节流 来优化我们的性能。

防抖 && 节流

节流:在一定时间内,触发多次事件,只认第一次触发的,到了时间结束执行事件

 function throttle(fn, time) {
            let oldTime = 0,
                timer = null;
            return () => {
                const nowTime = new Date()
                if (nowTime - oldTime >= time) {
                   fn()
                   oldTime = nowTime
                }
            }
        }

防抖:在一定时间内,触发多次事件,只认最后一次触发的并且重置时间,到了时间结束执行事件

function debounce(fn, time) {
            let timer = null
            return () => {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    fn()
                }, time);
            }
        }

在这里debounce有一个严重的问题就是如果用户一直触发事件,用户会一直得不到响应,所以我们可以借助防抖的思路来优化节流。

 function debounce(fn, time) {
            let oldTime = 0,
                timer = null;
            return () => {
                const nowTime = new Date()
                if (nowTime - oldTime < time) {
                    if (timer) {
                        clearTimeout(timer)
                    }
                    timer = setTimeout(() => {
                        oldTime = nowTime
                        fn()
                    }, time);
                } else {
                    // 用户重复触发,到达事件节点 还是会去执行事件 
                    oldTime = nowTime
                    fn()
                }
            }
        }

所以最后我们监听事件可以修改为containr.addEventListener('scroll', debounce(load, 1000), false),这就完美达到了我们优化的目的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前端防抖节流的使用场景很多。其中一种常见的场景是在用户输入搜索框时进行搜索提示。当用户快速输入时,如果每次输入都立即触发搜索请求,会造成过多的请求并降低性能。这时可以使用防抖来延迟执行搜索请求,只当用户停止输入一段时间后才触发搜索请求,避免不必要的请求。 另一个使用场景是在页面滚动时进行懒加载。当用户滚动页面时,如果每次滚动都立即加载图片或数据,会造成页面卡顿。通过使用节流,可以控制在一定时间内只触发一次加载,提高页面的流畅度。 此外,防抖节流还可以应用于按钮点击事件,防止用户频繁点击按钮导致重复提交或执行多次操作。通过设置适当的延迟时间,可以确保在用户点击按钮后只执行一次操作。 总之,前端防抖节流的使用场景包括搜索提示、懒加载和按钮点击事件等,通过延迟执行或控制触发频率,可以提升用户体验和页面性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [前端节流防抖的实景应用](https://blog.csdn.net/qq_52022825/article/details/125057737)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [防抖节流的封装函数与使用详解](https://download.csdn.net/download/weixin_38695061/14888196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值