datasrc

小说:朱丹,爱自己的你好美作者:陵纯杜伯更新时间:2019-03-22字数:82746

“还没完,他没那么容易死的。”步惊云嘶吼道,他可是见过刘皓全身上下都被开了那么多个小窟窿都一点事情都没有不将刘皓的脑袋摘下来步惊云都不会停止。

家居风水好,财运滚滚来(家居风水简单学)

“让殿下白跑一趟,韦滔心中不安,今天早点来,也是想向大将军道歉,顺便想叙叙旧。”
苏小暖听了叶扬的话后,差点没有憋住笑出来,但她还是冷冷的说道:“那你就跟着吧。”

在美国西南部内陆的内华达州,有着一座闻名世界的城市——拉斯维加斯。

datasrc


http请求

如果你学过计算机网络你就会知道,我们请求一个带有n张图片的html文件实际上会发送n+1次请求,因为在浏览器解析html的时候遇到了src,就会请求src后面的内容。

设想一下如果我们的页面有1000000张图片,那么如果等待这些图片响应成功并加载完时延是非常大的,而且图片的加载是同步的,加载时会阻塞浏览器继续向下解析,用户体验非常差。

那么我们可不可以让图片按需加载呢?当图片出现在可视区的时候再加载它而不是一开始就加载完全部图片。

图片懒加载

template:

<div @scroll="lazyLoad" ref="lazy">
    <img v-for="(src, index) in imgs" src="##" :dataSrc="src" :key="index">
    <!--more img-->
</div>

改变图片src

监听最外层div的滚动事件,触发滚动时遍历图片检测图片位置,若在可视区内则显示

loadImg() {
    var img = this.$refs.lazy.getElementsByClassName("lazyImg"); 
    // 已滚动高度+可视区高度
    var top = this.$refs.lazy.scrollTop + this.$refs.lazy.clientHeight;
    
    for(var i = 0; i < img.length; i++) {
        if(img[i].offsetTop <= top) {  // 在可视区内则显示图片
            img[i].src = img[i].getAttribute("datasrc");
        }
    }
},
lazyLoad() { 
    this.loadImg();
}

以上就实现了一个图片懒加载,本篇文章就到这里,再见。

桥豆麻袋,突然发现一个严重的问题:滚动过程中会不断触发lazyLoad对图片做一个遍历并判断,那么就会做无数次for循环,更可怕的是,修改一次src会发送一个请求,在滚动的时候我们的for循环每次都从头判断并修改src请求图片,那么请求次数可想而知。

函数防抖

如果在滚动过程中不断触发遍历并判断图片是否在可视区的监听事件,会耗费很大的性能,这里采用函数防抖:当用户停止滚动时统一遍历判断图片位置

debounce(fn) {
    // 函数防抖:用户停止操作之后触发
    clearTimeout(this.timer);
    this.timer = setTimeout(() => {
        fn();
    }, 1000);
}

我们可以将加载图片的方法放在debounce中

lazyLoad() {
    this.debounce(this.loadImg);
}

这样当用户滚动页面时,松开手才会执行loadImg来遍历判断图片位置。

又出现了一个问题:如果用户在滚动时从页面底部上拉到顶部一直没有松手,那么在这期间都不会执行loadImg,这意味着页面的图片都不会显示,非常影响用户体验

防抖优化

我们规定,若用户上拉高度大于500px那么就自动加载一次可视区内图片,这里我们用oldScrollTop记录上次上拉高度

lazyLoad() {
    // 如果上拉距离大于500px则自动加载
    if(this.$refs.lazy.scrollTop - this.oldScrollTop > 500) {
        this.loadImg();
        this.oldScrollTop = this.$refs.lazy.scrollTop; // 更新oldScrollTop
    } else {  // 如果向下拉但小于500px则防抖加载
        this.debounce(this.loadImg);
    }
}

下拉优化

当用户下拉的时候我们并不需要执行lazyLoad,因为我们之前的图片已经加载过了,所以可以修改一下lazyLoad

lazyLoad() {
    // 如果上拉距离大于500px则自动加载
    if(this.$refs.lazy.scrollTop - this.oldScrollTop > 500) {
        this.loadImg();
        this.oldScrollTop = this.$refs.lazy.scrollTop;
    } else if(this.$refs.lazy.scrollTop - this.oldScrollTop < 0) {  // 如果向下拉则不做操作
        return ;
    } else {  // 如果向下拉但小于500px则防抖加载
        this.debounce(this.loadImg);
    }
}

减少遍历个数

最重要的优化已经做完了,但是还可以从一些小细节更加优化一下,我们的loadImg方法中每次都是从0号下标开始遍历检查图片,但是在用户上拉操作之后一部分图片已经被加载了,就不需要再次去检查了。

我们可以用一个变量len记录上一次被加载后的最后一个图片,然后修改一下loadImg

 loadImg() {
    var img = this.getImages(); 
    var top = this.$refs.lazy.scrollTop + window.screen.height;
    
    // 从len开始检查
    for(var i = this.len; i < img.length; i++) {
        if(img[i].offsetTop <= top) {
            img[i].src = img[i].getAttribute("datasrc");
            this.len = i;  // 更新len
        }
    }
}

结语

一个完整的优化版图片懒加载就完成了,我将该功能封装成了一个vue的插件

源码:vue-plugins

该插件库会持续更新,欢迎star & fork~ 

当前文章:http://zxqss.com/forum.php?mod=viewthread&tid=55949

发布时间:2019-03-22 01:24:34

女人的速度 心理现象:心理饱和 他们凭什么成为罗德学者 幼师对儿童心理成长的重要作用(详) 打破水银温度计了怎么办 一点儿都不蠢 你真的适合创业吗?答案是“未必”! 旅途中一见钟情,咋办?

突破“离婚”或“凑合过”的婚姻困惑 让脖子走出冷宫 罗李华谈:属狗的人2016年运程 妖女的榜样 你敢不敢把手机借给陌生人? 我的意中人是个盖世英雄 刘墉:爱他!少骂他!一 有良心的孩子自己会觉悟 哪个朝代当官好? 罗李华谈:属马的人2016年运程 易经大师罗李华浅谈艺名 做好朋友,找真朋友 24个细节深度解读《美人鱼》 男性国人学习爱 她是热播剧中女一号,被黑得惨不忍睹,结局却如此励志 胤然体歌词 - 黄胤然首倡文创新理念 护肤必备手册之(二)周期护理 为了孩子,父母该不该守住破碎的婚姻 旅途中一见钟情,咋办? 从四大名著浅说团队

编辑:文海

我要说两句: (0人参与)

发布