一张图片引发的思考---懒加载

最近在做一个图片list预览组件,在一组图片list 中点击其中一张图片 可以放大 缩小,旋转、下载等功能。 但是list 中可能很多图片,如果首次打开这个页面, 每个图片都加载,浪费服务器资源,也给页面渲染带来极大的性能损耗。(http请求是宝贵的);
一.如何做到懒加载 也叫按需加载?
懒加载原理 ,初始化时候给页面的img 标签的src属性 ,默认赋值loading图片,增加一个 自定义的data-src 属性 ,存放真实的图片地址,遍历判断img 标签在视口中 , 把data-src 中的真实地址,赋值给src属性 ,加载真实的图片。
二.如何判断img 标签已经在视口
原始的转化方式 :
1. document.documentElement.clientHeight获取屏幕可视窗口高度 ,
2.el.offsetTop 获取元素距离文档顶部的 距离,
3.document.documentElement.scrollTop 文档向下滚动的距离。 如下图 当 ② - ① < ③    说明图片已经在视口内部。可以加载。

现成的API    getBoundingClientRect  :
浏览器提供 Element.getBoundingClientRect() 方法来获取元素的大小以及位置,包括 矩形 盒子的大小,top 、left、bottom  right 。
如下图。这些位置信息是相对视口 左上角为原点返回的数值。什么情况下是img 进入视口的呢?  假设,我们获取img 相对视口的信息 const  coordinateData= el.getBoundingClientRect() ,  const clientHeight = window.innerHeight , 很容易 coordinateData.top ===clientHeight 的 时候 ,img 将要进入视口。ok 

function isInViewport(el){
try{
   const {top,left,bottom,right}= el.getBoundingClientRect();
  const height= window.innerHeight;
  const width = window.innerWidth;
  const yInView = top<height&&bottom>0;
  const xInView = left<width&&right>0;
  return yInView&&xInView;
}catch(err){}
}

function getImgs(){
const imgs=  document.querySelectorAll('.photolist') ;
 Array.from(imgs).forEach(item=>{
    if (isInViewport(item)){
     if (item['data-isLoaded'])return;
     item.src = item['data-src'];
     item['data-isLoaded'] = true;
     }
})
}

上面的 代码 还为已经加载的img 标签添加了自定义属性,  如果该标签已经加载过图片, 以后的遍历就不会重新加载。
这里还可以优化下, 在页面滚动的时候 ,一直去访问dom 执行操作,对页面性能是很大的损耗。 这里我们可以写一个节流函数,
具体解释看这里;


function throttle(fn,delay){
   let deferTimer , last;
    return function (args){
      const context = this;
      const now = new Date();
      const _args = arguments;
   if(last&&now<last + delay){
     if(!deferTimer){
   deferTimer = setTimeout(()=>{
       fn.apply(context,_args);
       last=now;
      clearTimeout(deferTimer)
     },last+delay-now);
   }
} else {
    fn.apply(context,_args);
    last=now;

}
    }

}

window.addEventListener('scroll',()=>{
throttle(getImgs(),500ms)
});
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值