[js] 图片懒加载

懒加载使用场景

在一些图片量比较大的场景(电商首页,小程序首页等),如果我们打开页面时就加载所有的图片,那势必会导致页面的卡顿以及白屏,给用户不好的体验,导致用户流失。
但是我们仔细想一下,用户真的需要我们显示所有图片一起展示吗?其实并不是,用户看到的只是浏览器可视区域的内容。所以从这个情况我们可以做一些优化,只显示用户可视区域内的图片,当用户触发滚动的瞬间再去请求显示给用户。

懒加载的思路

一张图片就是一个标签,浏览器是否发起请求图片是根据的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值

懒加载的问题

图片懒加载

  • 只有进入(即将进入)可是区域的图片才进行加载 item.src = item.dataset.src
  • 如果没有进入可视区域的图片不进行加载

问题1: 如果你希望实现图片懒加载, 那么渲染页面的时候, img 的 src 还能写吗 ?

  • 不能
  • 但是有需要直到该 img 标签应该引入的是哪一张图片
  • 所以我们以一个自定义属性的形式, 来把该 img 需要的图片地址记录在标签身上

问题2: 获取元素img

  • 不能在全局获取img

问题3: 当你第一次滚动的时候, 遍历所有图片,当你向下滚动的时候, 前面的图片已经加载过了,你再次遍历的时候还需要遍历吗 ? 不需要了

  • 如果这个 img 标签已经有 src 属性了, 说明已经加载过了,就不需要判断高度了
if (item.src) return

图片什么时候进入可视区域
在这里插入图片描述
当scrollTop+clientHeight> offsetTop时候,可以加载新的图片了

加个50px,提前一点点距离加载新的图片
在这里插入图片描述

懒加载的实现

  <ul>
  </ul>
    * {
      margin: 0;
      padding: 0;
    }

    li {
      margin: 30px;
      width: 340px;
      height: 548px;
      border: 2px solid #333;
    }

    img {
      width: 100%;
      height: 100%;
      display: block;
    }
var list = [{"id":625153951363,"name":"2020西太湖国际音乐节","showTime":"2020.09.19-09.20","price":"199-399","city":"常州","address":"常州西太湖中国花卉博览景区北门","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01zJEpaN2GdSG1Xvo8y_!!2251059038.jpg"},{"id":624506842658,"name":"2020舟山东海音乐节","showTime":"2020.09.04-09.06","price":"200-680","city":"舟山","address":"舟山市朱家尖南沙景区沙滩","pic":"https://img.alicdn.com/bao/uploaded/i4/2251059038/O1CN01L70FVl2GdSG2wpwyE_!!0-item_pic.jpg"},{"id":623216520608,"name":"中国•磐安 2020氧气山水音乐节","showTime":"2020.08.22 周六 16:30","price":"280","city":"金华","address":"金华磐安花溪风景区","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01ECp69h2GdSFpoUPAm_!!2251059038.jpg"},{"id":624345993344,"name":"2020“一生中最爱”七夕演唱会","showTime":"2020.08.25 周二 19:30","price":"180-580","city":"北京","address":"糖果TANGO-雍和宫店三层","pic":"https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01WGNYBE2GdSFqXJgII_!!0-item_pic.jpg"},{"id":624170605605,"name":"东海五渔节之敢潮音乐节","showTime":"2020.08.22 周六 18:00","price":"198-228","city":"舟山","address":"舟山嵊泗五龙乡听海广场(原黄沙村船厂)","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i1/2251059038/O1CN01eV5pR32GdSFxJUb0v_!!2251059038.jpg"},{"id":624000957041,"name":"【聚光灯】周四周日爆笑脱口秀剧场","showTime":"2020.08.13-09.27","price":"99","city":"上海","address":"健力士醇黑坊","pic":"https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01s9Jlz32GdSFv79hIO_!!0-item_pic.jpg"},{"id":623838540974,"name":"2020真世界摇滚演出","showTime":"2020.08.29 周六 20:30","price":"120","city":"北京","address":"糖果TANGO-雍和宫店三层","pic":"https://img.alicdn.com/bao/uploaded/i2/2251059038/O1CN01HWbQXk2GdSFxARpRD_!!0-item_pic.jpg"},{"id":624699066028,"name":"开心麻花首部悬疑惊悚喜剧《醉后赢家》","showTime":"2020.08.25-09.06","price":"80-1080","city":"北京","address":"地质礼堂剧场","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i2/2251059038/O1CN01Vv1mQO2GdSFvnmIDs_!!2251059038.png"},{"id":625219995330,"name":"开心麻花经典爆笑舞台剧《乌龙山伯爵》","showTime":"2020.08.25-08.30","price":"80-1080","city":"北京","address":"北京展览馆剧场","pic":"https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01znXuKj2GdSG6ACMMb_!!0-item_pic.jpg"},{"id":623454281510,"name":"开心麻花重磅新戏《贼想得到你》","showTime":"2020.08.12 周三","price":"80-1280","city":"上海","address":"上汽上海文化广场","pic":"https://img.alicdn.com/bao/uploaded/i1/2251059038/O1CN013YAyeY2GdSFnXwgnQ_!!0-item_pic.jpg"},{"id":625314963280,"name":"开心麻花重磅新戏《贼想得到你》","showTime":"2020.08.15-08.21","price":"100-1180","city":"上海","address":"虹桥艺术中心","pic":"https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01Qb8wyX2GdSG30DCl4_!!0-item_pic.jpg"},{"id":622815888793,"name":"开心麻花上海首部原创爆笑舞台剧《皇帝的新娘》","showTime":"2020.08.12-08.16","price":"80-1180","city":"上海","address":"上戏实验剧院","pic":"https://img.alicdn.com/bao/uploaded/i2/2251059038/O1CN01uie4Gf2GdSFlp1Rvv_!!0-item_pic.jpg"},{"id":624443634831,"name":"孟京辉戏剧作品《我爱xxx》","showTime":"2020.08.13-08.16","price":"100-380","city":"北京","address":"蜂巢剧场","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01LwdJRL2GdSFtDPtRL_!!2251059038.jpg"},{"id":624095704875,"name":"【8月8日-16日场次周年特惠低至四折】太阳马戏X绮幻之境 - 8月","showTime":"2020.08.12-08.30","price":"360-3460","city":"杭州","address":"杭州新天地太阳剧场","pic":"https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01iyWOwU2GdSG2iMBsM_!!0-item_pic.jpg"},{"id":624163106935,"name":"高达5公里定向挑战赛","showTime":"2020.09.26 周六","price":"108-388","city":"上海","address":"世纪公园","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01y2n1PI2GdSFtLmEtu_!!2251059038.jpg"},{"id":622064265074,"name":"2020 FORMULA1 中国大奖赛(礼包&福袋)","showTime":"2020.07.04-12.31","price":"120-270","city":"上海","address":"上汽国际赛车场(上海国际赛车场)","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i2/2251059038/O1CN01ZHrnGM2GdSFbZjdUV_!!2251059038.jpg"},{"id":623662985515,"name":"2020ChinaJoy电竞赛事荟萃","showTime":"2020.07.31-10.30","price":"0","city":"北京","address":"请到大麦APP和优酷APP观看","pic":"https://img.alicdn.com/bao/uploaded/i4/2251059038/O1CN01RpgBQ82GdSFoMD7h8_!!0-item_pic.jpg"},{"id":618307700815,"name":"2020 FORMULA1 中国大奖赛(服装)","showTime":"2020.05.19-12.31","price":"248-620","city":"上海","address":"上汽国际赛车场(上海国际赛车场)","pic":"https://img.alicdn.com/bao/uploaded/i2/2251059038/O1CN01scI6Ly2GdSFEYDh7P_!!0-item_pic.jpg"},{"id":613334933912,"name":"2020 FORMULA1 中国大奖赛(周边衍生品)","showTime":"2020.03.11-12.31","price":"35-160","city":"上海","address":"上汽国际赛车场(上海国际赛车场)","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01ZusbUY2GdSENL0iIN_!!2251059038.jpg"},{"id":613323173822,"name":"2020 FORMULA1 中国大奖赛(帽品)","showTime":"2020.03.11-12.31","price":"200-335","city":"上海","address":"上汽国际赛车场(上海国际赛车场)","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01azreXu2GdSF9rIkGV_!!2251059038.jpg"},{"id":613940057617,"name":"加速北京跳伞俱乐部高空跳伞体验","showTime":"2020.08.05-08.31","price":"2980","city":"北京","address":"北京市平谷区马坊镇通航产业基地","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i1/2251059038/O1CN01Ns9MZj2GdSFIp2udB_!!2251059038.png"},{"id":624453755826,"name":"《你是演奏家2 · 超级金贝鼓》","showTime":"2020.08.21-08.23","price":"180-380","city":"上海","address":"美琪大戏院","pic":"https://img.alicdn.com/bao/uploaded/i4/2251059038/O1CN016u70M62GdSFrTL5GP_!!0-item_pic.jpg"},{"id":624211844323,"name":"正版授权·大型儿童实景舞台剧《奥特曼宇宙之光》","showTime":"2020.09.05 周六","price":"180-580","city":"海口","address":"海南省歌舞剧院","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i2/2251059038/O1CN01ybwkiZ2GdSFy9894v_!!2251059038.jpg"},{"id":624672730925,"name":"全国正版授权大型互动式儿童舞台剧 海底小纵队2—火山大冒险","showTime":"2020.11.15 周日","price":"80-480","city":"上海","address":"黄浦剧场-中剧场","pic":"https://img.alicdn.com/bao/uploaded/i1/2251059038/O1CN01mfDv5t2GdSFwbhzvt_!!0-item_pic.jpg"},{"id":624868314578,"name":"大船文化·加拿大原版音乐启蒙全场互动亲子剧《你是演奏家2·超级金贝鼓》","showTime":"2020.09.06 周日","price":"180-380","city":"天津","address":"津湾大剧院大剧场","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i4/2251059038/O1CN01l16ZUE2GdSFzGWSPx_!!2251059038.png"},{"id":624450522367,"name":"大船文化·法国艺术启蒙魔术剧《美术馆奇妙夜·星夜》中文版","showTime":"2020.09.06 周日","price":"120-280","city":"南京","address":"江苏大剧院--综艺厅","pic":"https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01FMizHi2GdSG0AINxP_!!2-item_pic.png"},{"id":623125350409,"name":"大船文化 法国艺术启蒙魔术剧《美术馆奇妙夜·星夜》中文版","showTime":"2020.08.27-08.30","price":"80-480","city":"上海","address":"上汽上海文化广场","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i4/2251059038/O1CN01CiAVft2GdSFpIawAw_!!2251059038.jpg"},{"id":623975390263,"name":"正版授权大型实景舞台剧《奥特曼:宇宙之光》(杭州站)","showTime":"2020.12.13 周日","price":"68-480","city":"杭州","address":"杭州剧院","pic":"https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i4/2251059038/O1CN01fUBSCY2GdSFsbnPPh_!!2251059038.jpg"}]

    const ul = document.querySelector('ul')

    bindHtml()
    // 1. 渲染页面
    function bindHtml() {
      let str = ''
      list.forEach(item => {
        str += `<li><img data-src="${ item.pic }" alt=""></li>`
      })
      ul.innerHTML = str

      // 只要渲染完毕页面, 执行 lazyload 图片懒加载
      lazyload()
    }

    // 2. 实现图片懒加载
    function lazyload() {
      const imgs = ul.querySelectorAll('img')

      // 2-1. 遍历拿到每一个 img
      imgs.forEach(item => {

        // 优化处理
        // item 就是每一个 img 标签
        // 如果这个 img 标签已经有 src 属性了, 说明已经加载过了,就不需要判断高度了
        if (item.src) return

        // 2-2. 拿到每一个图片距离顶部的尺寸
        const img_top = item.offsetTop
        const window_height = document.documentElement.clientHeight
        const scroll_top = document.documentElement.scrollTop || document.body.scrollTop

        // 2-3. 判断某一张图片进入页面了
        if (img_top - 50 <= window_height + scroll_top) {
          // 需要加载当前这一张图片了
          item.src = item.dataset.src
        }
      })
    }

    // 要求 lazyload 随着浏览器的滚动随时执行
    window.onscroll = function () {
      lazyload()
    }

在这里插入图片描述





参考: [前端性能优化-图片懒加载(防抖、节流)](https://juejin.cn/post/6844904035258990606)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值