文档章节

前端图片延迟加载详细讲解

梅气灶
 梅气灶
发布于 2015/08/22 21:40
字数 1414
阅读 6377
收藏 285

        原本是打算昨天昨天下午的时候就写一篇关于前端图片延迟加载的详细技术的博客的,没想到下午公司项目出现了一些问题,所以一直在改代码进行调试,今天白天一整天又在外面跑,回来已经傍晚了,刚吃完饭,就想着赶紧补上,这样很多不懂这方面具体实现的小伙伴们也能早点学习经验。

         前端页面的用户体验对于一个网站来说是至关重要的,我们在访问一些图片量比较大的网站的时候,往往会有这样的感受:显示在我电脑屏幕可视区域的图片总是不能及时的刷出来,这就造成了对于一些没有什么耐心的用户而言,他们就不愿意多等下去,索性直接关闭了网站去看其他的网站,这就使得本网站的用户量的流失,这往往是一个网站最不愿意看到的情况,那么对于这样的情况而言,开发者们不断的努力,很快就想到了解决的方案,让在可视区域的图片立即加载进来,而让不在可视区域并且需要通过滚动条进行滚动显示的图片在图片滚动到可视区域内再显示出来,这就比一次性把所有的图片资源加载进来从而造成图片刷新较慢的用户体验好的多的多。

         那么,图片延迟加载的技术具体如何实现呢?下面来做详细的介绍:

         首先,定义图片为三列,一共有5行,具体代码如下:

        

        

        里面用到的bootstrap的布局技术(当然,这不是重点),请看img标签中的src,一开始我们并没有给它具体的图片的资源路径,而是自己定义了一个属性 x-src,该属性的值是图片图片的资源路径,每一行的img都是如此,接下来,当页面载入的时候,我们使用jquery(当然,你想javascript原生的代码也可以,我这里只是为了省时间而已)来循环遍历每一个img,判断每一个图片是否在当前可视区域内,是则显示图片,否则稍后处理,这里需要知道三个数据:

                 注:因为我所写的是当图片的一半进入的浏览器的可视区域内才将这张图片进行加载,所以需要第            三 个数据,这个看个人的需求是什么,如果你的需求是图片只要已进入可视区域内就加载,可直接忽略            第三个数据!!!!

                                 1:浏览器可视区域的高度

                                 2:图片相对于文档的偏移量(这里只需要高度上的偏移量)

                                 3:图片元素本身的高度

        如果图片先对于文档的偏移量+图片元素本身的高度的一半    <  浏览器可视区域的高度,即表明图片已经有一半进入的可视区域了,那么我就应该要把这张图片加载进来了,可是img标签的src是为空的,x-src的值才是图片的资源路径,这个时候就需要用jquery将img 标签的x-src值传给src,从而将图片加载进来,具体实现代码如下:

        

        具体的效果如下:

        

         你可以在控制台看到,虽然我们有5行图片,每行有3列,但加载进来的图片只有第一列(图片高度有超出一半的img才会加载图片的资源进来),其他的都没有加载进来,这就使得图片的刷新会很快出现效果,那么接下来,用户需要看到更多的图片,这个时候需要进行滚动条往下滚动,去刷新更多的图片,那么这个时候我们除了上述的3个数据之外,还需要知道当前滚动条滚动的距离,如果:

                图片先对于文档的偏移量+图片元素本身的高度的一半    <  浏览器可视区域的高度  + 当前滚动条滚动的距离,那么表明当前图片已经在可视区域内,并且图片有一半以上的高度是在可视区域内,那么将图片进行加载进来,具体代码如下:

        

        具体效果如下:

        

         在控制台你可以看到,随着滚动条的滚动,加载进来的图片由原来的三张变成了现在的六张,滚动条不断的往下滚动,图片就会不断的加载进来,从而得到更好的用户体验。

        这就是图片延迟加载的具体实现,是不是觉得图片的炫酷,如果你想自己看下具体的实现效果,可以点击我的网址进行查看:

                http://meichao.sinaapp.com/show.html          (请打开开发者工具查看具体的加载过程)

         如果还有什么不明白的,可以直接QQ联系本人:447247261                    欢迎大家一起相互探讨,相互进步

© 著作权归作者所有

梅气灶
粉丝 30
博文 15
码字总数 20372
作品 0
杭州
前端工程师
私信 提问
加载中

评论(16)

洽汇网
洽汇网

引用来自“Micooz”的评论

假设我要在一个页面内显示一万张图片,利用延迟加载,每次滚动都要遍历img,效率会很低,有没有更好的解决方案?
楼主的代码我进行了二次优化,麻烦楼主改下代码,让码农不用担心遍历效率
$(window).scroll(function(){
$('img[src=""]').each(function(){//查找src=""的图片
if(($(this).offset().top+$(this).width()/2) < $(window).height()+$(window).scrollTop()){
$(this).attr(‘src’,$(this).attr('x-src'));
}else{return false;}//直接退出遍历
});
});
郭大侠
郭大侠

引用来自“梅雨夕”的评论

引用来自“尘梦无痕醉光阴”的评论

图片懒加载而已
确实只是图片懒加载而已,而我只是把我的理解写出来而已,用图文的方式让更多的人了解而已

这只是一篇好文,咱把它收了而已!
梅气灶
梅气灶 博主

引用来自“尘梦无痕醉光阴”的评论

图片懒加载而已
确实只是图片懒加载而已,而我只是把我的理解写出来而已,用图文的方式让更多的人了解而已
秋风暮霞惋红曲
秋风暮霞惋红曲
图片懒加载而已
陈阳阳阳
陈阳阳阳

引用来自“Micooz”的评论

假设我要在一个页面内显示一万张图片,利用延迟加载,每次滚动都要遍历img,效率会很低,有没有更好的解决方案?
已经加载的肯定不用遍历了,另外根据图片的大小你能判断出一个页面最多显示多少张图片,设置一个遍历最大值比如100即可。
梅气灶
梅气灶 博主

引用来自“chape”的评论

基础思想是这样的,但是实际场景一般是ajax获取图片地址列表,动态构建图片展示区域的DOM节点树吧
这里只是纯静态网页而已,如果要加上后台的话,那么使用ajax,在回调函数中得到的肯定是图片的资源地址(可以是数据库里获取到的,也可以直接给个json),然后根据需求,动态构建图片展示区域的dom节点树
chape
chape
基础思想是这样的,但是实际场景一般是ajax获取图片地址列表,动态构建图片展示区域的DOM节点树吧
稻草鸟人
稻草鸟人
不错不错哦
ifuture
ifuture

引用来自“Micooz”的评论

引用来自“梅雨夕”的评论

引用来自“Micooz”的评论

假设我要在一个页面内显示一万张图片,利用延迟加载,每次滚动都要遍历img,效率会很低,有没有更好的解决方案?
其实可以不用遍历所有的img,已经显示了的Img我们就直接忽略了的,然后在未加载部分的img,我的想法是:每次都把不在可视区域内的图片先预先加载几行进来(假设一行有3张),这样用户在滚动滚动条的时候就可以不用再去请求了,而我们不需要遍历img,只是去多去加载了几张图片而已。

嗯,你的意思我理解,假定条件判定和图片加载的时间可忽略,实际上你的each回调仍然每次都会执行1w次,性能问题出在频繁的1w次回调,如何解决?

1 加break 2 给每个img加一个按顺序排列的I'd
Micooz
Micooz

引用来自“梅雨夕”的评论

引用来自“Micooz”的评论

假设我要在一个页面内显示一万张图片,利用延迟加载,每次滚动都要遍历img,效率会很低,有没有更好的解决方案?
其实可以不用遍历所有的img,已经显示了的Img我们就直接忽略了的,然后在未加载部分的img,我的想法是:每次都把不在可视区域内的图片先预先加载几行进来(假设一行有3张),这样用户在滚动滚动条的时候就可以不用再去请求了,而我们不需要遍历img,只是去多去加载了几张图片而已。

嗯,你的意思我理解,假定条件判定和图片加载的时间可忽略,实际上你的each回调仍然每次都会执行1w次,性能问题出在频繁的1w次回调,如何解决?
前端基础知识

Understanding ECMAScript 6 中文版(可下载电子书) Nicholas C. Zakas 大神的新著作,2016 年 8 月 30 日出版。 在 GitBook 页面上阅读本书全文,也可以下载 PDF 、 Mobi 或 ePub 格式的电...

掘金官方
2017/12/12
0
0
图片延迟加载插件--SuperImageLoader.js

大家还在为网页加载速度而烦恼吗?大家有发现网页在某些浏览器很快,而在某些浏览器却很慢吗?今天向大家介绍一下为何会出现这些情况,并给大家分享一下具体的实现方法 1.先向大家讲解一下为...

优新世纪-恋空
2017/06/21
1K
7
Android应用启动优化:一种DelayLoad的实现和原理

今天看到一篇讲关于延迟加载机制的文章,在时间调度上堪称完美,所以转载过来记录。 原文链接:http://androidperformance.com/2015/11/18/Android-app-lunch-optimize-delay-load.html 下篇...

yizhihaohut
2016/08/18
25
0
jQuery

前端基础进阶:全方位详细图解面向对象、构造函数、原型与原型链 这是一篇非常适合新手理解关于面向对象一切的文章,解答了为什么我们会使用构造函数与原型,构造函数与原型的本质以及 new ...

掘金官方
2018/01/08
0
0
Java Web 前端高性能优化(一)

---Web 发展的速度让许多人叹为观止,层出不穷的组件、技术,只需要合理的组合、恰当的设置,就可以让 Web 程序性能不断飞跃。所有 Web 的思想都是通用的,它们也可以运用到 Java Web。这一系...

OneAPM蓝海讯通
2015/12/04
185
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud 笔记之Spring cloud config client

观察者模式它的数据的变化是被动的。 观察者模式在java中的实现: package com.hxq.springcloud.springcloudconfigclient;import org.springframework.context.ApplicationListener;i...

xiaoxiao_go
今天
4
0
CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
今天
4
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
今天
7
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
今天
7
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部