网站优化之如何用原生javascript去完成懒加载技术--lazyload

前几天,技术总监说,我们现在的很多站点加载出来需要很长的时间。你去想办法去优化一下,看能不能提高加载速度,增加用户体验。然后我就去访问了下站点,发现所有的站点都有同一个问题。就是加载图片耗费了大量的时间。

既然是图片的问题,那就压缩图片吧。压完更新后,发现有效果,但是治标不治本。于是就找了几种解决方法:

1.lazyload

2.延迟加载(用setTimeout去做,有点不着调啊)

3预加载(此方法适用于增加用户体验,但是更加对服务器有压力了)

4.增加带宽,换好的服务器(你懂的,一般老板不到最后时刻都不会这样的)

那就只有lazyload的,当然,这只是现在能想到的几种方法。趋势上网搜了下,有jq的插件。

<img class="lazy" data-original="img/bmw_m1_hood.jpg">
<img class="lazy" data-original="img/bmw_m1_side.jpg">
<img class="lazy" data-original="img/viper1.jpg">
<img class="lazy" data-original="img/viper_corner.jpg">
<img class="lazy" data-original="img/bmw_m3_gt.jpg">
<img class="lazy" data-original="img/corvette_pitstop.jpg">

相信看过lazyload说明的都知道,他的图片路径要写在data-original里面。那一般就把代码里面有关img标签里面的img的路径改了,然后就是引入那个jq 和lazyload的两个js文件,最后就是
<pre name="code" class="html"><script type="text/javascript" charset="utf-8">
  $(function() {
      $("img.lazy").lazyload({effect: "fadeIn"});
  });
</script>


 以为这样就行了,但是!关键是但是!我所在的公司是做智能建站系统的,那么基本不可能去修改里面img标签的,因为那是自动生成的。后台添加的,我们只能在公共区域引入js,所以只能获取到img标签的元素。然后就有了接下来的故事。 

本着既然这是人写出来的,那么他行我也行(虽然我也是只菜鸟,但是是一个执着的菜鸟。哈哈)

我们先整理下思路:

lazyload的本质是在图片快要进入屏幕可视区域的时候加载,

第一步:dom树加载完毕图片加载之前,让所有图片都不能加载(img的src=“”);

第二步:dom树加载完成之后加载可视区域和接近可是区域的图片;

第三部:当滚动时触发快要进入屏幕可视区域的时候加载图片(onscroll事件);

准备工作:

1.

function getPageScroll() {
  var xScroll, yScroll;
  if (self.pageYOffset) {
    yScroll = self.pageYOffset;
    xScroll = self.pageXOffset;
  } else if (document.documentElement && document.documentElement.scrollTop) {
    yScroll = document.documentElement.scrollTop;
    xScroll = document.documentElement.scrollLeft;
  } else if (document.body) {
    yScroll = document.body.scrollTop;
    xScroll = document.body.scrollLeft;  
  }
  function man(lol,dota){
  this.xx=lol;
  this.yy=dota;
  }
  arrayPageScroll = new man(xScroll,yScroll)
  return arrayPageScroll;
};

这是获取滚动距离的js代码,已经考虑的兼容性;

2.function caltop(vrobj){
    var vtop=vrobj.offsetHeight;
    while(vrobj.offsetParent){
    vtop+= vrobj.offsetTop;
    vrobj = vrobj.offsetParent;
}
return vtop;
}

获取元素的相对于浏览器的高度;

3.

$(function(){
    var hh=getPageScroll();  //hh保存了一个关于scrolltop的对象
    var tupian=document.getElementsByTagName('img');//获取所有的图片元素

    var a =[];
    var b=[];

    $('img ').each(function(){
    var wzd=this.getAttribute('wzd');
        a.push(wzd);
    })
    
    $(tupian).attr('src','');
    $(tupian).animate({
        opacity: 0,
    }, 10);
    $(tupian).each(function(){
    b.push(this);
    
    });    
    $(b).each(function(){
        if(($(this).position().top-hh.yy-$(window).height())<100){
    
        this.src=a[0];
        this.οnlοad=function(){
            $(this).animate({
            opacity: 1,
            }, 1000);
        }
        b.shift();
        a.shift();
        console.log('2');        
        }    
    });

document.οnscrοll=function(){
        hh=getPageScroll();
        $(b).each(
            function(){
                if((caltop(this)-hh.yy-$(window).height())<100){
                this.src=a[0];
                this.οnlοad=function(){
                $(this).animate({
                opacity: 1,
                }, 1000);
        }
                b.shift();
                a.shift();
                
                console.log('1');
                }
                    
            }        
        )    
    }

});


如果你写过onscroll事件,如果你知道你滚动下滚轮触发了很多次回调函数,如果你也想方设法的想过稀释函数回调,如果你也尝试过多次的img加载,你就知道我在里面定义数组的原因,为什么要用shift去删除元素,你就知道我写这个代码时遇到的各种bug

最终的测试结果


的确实现了按需求加载,让接近可视区域的加载。但是只要你把图片放在src里面,那么就会这样,我们是在dom树加载完成之后强制行的把src清空。所以还是会有一点点的性能浪费。所以插件里面将链接引入data-origin是更好的做法。但是却不适合我现在遇到的问题。

现在还在想如何解决这样一个事件。有了新的进展再和大家分享。如有大神请指出如何解决这样的事。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值