图片的懒加载

背景:如果不使用懒加载,页面加载后,列表内所有的图片均会被浏览器加载,消耗资源,用户体验非常差,懒加载是性能优化的基础之一。

想做的就是让图片按需加载,触发滚动时遍历图片检测图片位置,若在可视区内则显示。

另外了解一下:
window.onload()--等待网页中所有内容加载完毕之后(包括图片)才能执行。
jQuery中$(docoment).ready --在网页所有的DOM结构绘制完毕就执行,可能DOM元素关联的东西并没有加载完。

1.改变图片的src(见4的优化)

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

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

// methods:
loadImg () {
   var img = this.$ref.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('data-src')
        }
    }
}
lazyLoad () {
    this.LoadImg()
}

图片的src属性为空,使用data-src属性写上需要加载的图片的路径url,在懒加载的代码中,将src属性的值替换成对应的data-src。

2. vue中使用vue-lazyload

2.1 安装

npm -i vue-lazyload -S
或者引入CDN: https://unpkg.com/vue-lazyload/vue-lazyload.js

2.2 使用

main.js

import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload)
// or with options
Vue.use(VueLazyload, {
   preLoad: 1.3,
   error: 'dist/error.png',
   loading: 'dist/loading.gif' //项目存放图片的路径
   attempt: 1
})

template:

<ul>
    <li v-for="img in list">
        <img v-lazy="img.src">
    </li>
</ul>

use v-lazy-container work with raw HTML and custom error and loading placeholder image

 <div v-lazy-container="{ selector: 'img', error: 'xxx.jpg', loading: 'xxx.jpg' }">
    <img data-src="//domain.com/img1.jpg">
    <img data-src="//domain.com/img2.jpg">
    <img data-src="//domain.com/img3.jpg">  
  </div>

2.3 了解属性:

key description default options
preLoad 预载的高度比例 1.3 Number
error 加载失败时src 'data-src' String
loading 加载图片时src 'data-src' String
attempt 常识次数 3 Number
listenEvents 监听的事件 ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']
adapter 动态修改element属性 { }
filter 图像的侦听器过滤器 { }
lazyComponent 延迟加载组件 false
dispatchEvent 触发dom事件 false Boolean
throttleWait 200 Number
observer false Boolean
observerOptions { rootMargin: '0px', threshold: 0.1 }
silent true Boolean

2.4 CSS state

<img src="imgUrl" lazy="loading">
<img src="imgUrl" lazy="loaded">
<img src="imgUrl" lazy="error">
<style>
    img[lazy=loading] {
        /*your style here*/
    }
    img[lazy=error] {
        /*your style here*/
    }
    .yourclass[lazy=loading] {
        /*your style here*/
    }
</style>

2.5 效果图

正在加载的图片们

3. 拓展:各种宽高

页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;

4.优化1

监听滚动事件,在滚动过程会不断触发lazyLoad对图片做一个遍历并判断,那么就会做无数次for循环,修改一次src会发送一个请求,在滚动的时候for循环每次都从头判断并修改src请求图片,那么请求次数可想而知。

函数防抖

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

debounce(fn) {
    // 函数防抖:用户停止操作之后触发
    clearTimeout(this.timer);
    this.timer = setTimeout(() => {
        fn();
    }, 1000);
}
// 将加载图片的方法放在debounce中
lazyLoad() {
    this.debounce(this.loadImg);
}

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

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

防抖优化

若用户上拉高度大于500px 那就自动加载一次可视区内图片,当用户下拉时并不需要执行。

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);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 背景和原理   浏览器在解析网页时会解析整个HTML代码,一般情况下,浏览器会请求其中所有的图片并把它们都下载下来...
    Gettingjie阅读 210评论 0 2
  • 一、原理 在浏览器滚动的时候,遍历所有图片,若图片在视窗可视区域,则加载该图片 将图片地址存放在自定义属性中(da...
    饥人谷_js_chen阅读 633评论 0 4
  • 我们做一个网站的时候,有时候有很多的资源加载,比如说有大量的图片展示,图片一般情况下会消耗很多的资源,一个页面有上...
    郑宋君阅读 260评论 0 0
  • 也许你看到这个标题第一个想法就是,这不是 h5 同事去做的事吗,直接给个 url 地址,我们直接加载就行了。但是这...
    被风扬起的沙阅读 4,347评论 3 3
  • 采用JavaScript 获取到所有的img标签,然后遍历获取到原有的src内容,置换为占位图,在onload事件...
    神采飞扬_2015阅读 1,793评论 0 2