图片惰性加载 DEMO 地址 -> 图片惰性加载(放在了 Github 上,所以可能会慢,最好用 chrome

关于惰性加载


在讲图片的惰性加载前,我们先来聊聊惰性加载。惰性加载又称为延迟加载、懒加载等,还有个好听的英文名字叫做 "lazyload"。需要注意的是,惰性加载并不只是图片的专利,Javascript 中函数也有惰性加载的概念(详见 高性能JavaScript 编程实践 "不要重复工作" 一节),而在 Javascript 异步加载中还有个 LazyLoad类库,而图片的惰性加载库(lazyload)与之完全是两个概念,这些一定要弄清楚,以免混淆概念。

图片的惰性加载是啥意思?为什么要用它?当我们页面上的东西越来越丰富的时候,我们发现页面的加载速度却越来越慢,而图片的加载量无疑是 HTTP 请求里面的大头。其实很多时候,你把整个页面加载完,用户却不会滑动到最下面,也就是说很多东西其实白白加载了。因为图片的加载是大头,所以我们先拿图片开刀,我们假设,如果试图加载一个 HTML 页面,图片先不加载,当用户将页面往下滑动,图片该出现在可视区域时,再将该图片加载,这样就能将一开始打开页面的 HTTP 请求量降低,这就是图片的惰性加载。

实现


图片的惰性加载实现方式其实很简单。

  • 在 HTML 文件中将需要惰性加载的图片的 src 属性置为一个相同的地址(一般设置为一张 loading 图),这样这张图只会加载一次(第二次即会读取缓存),或者干脆置为空(用户体验不好),将真实的图片地址存储在别的属性中(比如 data-original 属性)
  • 监听事件(比如 scroll 事件),判断需要惰性加载的图片是否已经在可视区域,如果是,则将 src 属性替换成 data-original 属性值

接着我们来简单写下代码。

首先,按照第一步将真实的图片地址藏在 data-original 属性中。这里我假设所有图片都要进行惰性加载,现实开发中如果肯定是在第一屏的图片,它的 src 完全可以直接指向真实的地址。

复制代码<ul><li class='lazy'><img data-original='images/0.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/1.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/2.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/3.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/4.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/5.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/6.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/7.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/8.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/9.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/10.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/11.jpg' src='images/loading.gif'/></li> <li class='lazy'><img data-original='images/12.jpg' src='images/loading.gif'/></li> </ul>

因为我把所有图片都设置为惰性加载模式,而首屏的图片需要直接显示,这里我写了个 init() 函数,注释都在代码中了:

复制代码function init() {var images = document.images; // 加载首屏图片 for (var i = 0, len = images.length; i < len; i++) { var obj = images[i]; // 如果在可视区域并且还没被加载过 if (obj.getBoundingClientRect().top < document.documentElement.clientHeight && !obj.isLoad) { obj.isLoad = true; // 先调用 HTML5 方法 if (obj.dataset) imageLoaded(obj, obj.dataset.original); else imageLoaded(obj, obj.getAttribute('data-original')); } else { // 假设图片标签在 HTML 中的顺序和实际页面中顺序一致 break; } } }

代码中写了个 imageLoaded() 函数来将真实的图片地址指向元素,如果直接将 data-original 属性值指向图片的 src 属性的话,看到的图片可能会一段一段出现,而先将图片完全加载,然后再赋值使图片出现的话,体验就好多了。

复制代码function imageLoaded(obj, src) {var img = new Image(); img.onload = function() { obj.src = src; }; img.src = src; }

OK,接着我们监听 scroll 事件。当用户滑动页面,图片出现在可视区域时,随即加载图片。

复制代码window.onscroll = function() {lazyload();
};function lazyload() { var lazy = 0; var images = document.images; for (var i = 0, len = images.length; i < len; i++) { var obj = images[i]; if (obj.getBoundingClientRect().top - lazy < document.documentElement.clientHeight && !obj.isLoad) { obj.isLoad = true; if (obj.dataset) imageLoaded(obj, obj.dataset.original); else imageLoaded(obj, obj.getAttribute('data-original')); } } }

有的时候并不能当图片刚好在可视区域的时候再去加载,而要稍微 "预加载",可以调整下 lazyload() 函数中的 lazy 参数。

如果 "生硬" 地显示图片体验不大好,也可以搞点淡出效果,具体就不说了,可以看完整代码 Github

这样,一个简单的图片惰性加载 DEMO 就完成了!

PS:惰性加载虽然好处多多,但是也有一个 "非致命" 的缺点,影响 SEO。因为图片都被替换成假的图片,所以会影响图片的收录,所以这功能不建议在详情页使用

转载于:https://www.cnblogs.com/zhengxingpeng/p/6679061.html

教你实现图片的惰性加载相关推荐

  1. php的惰性加载,惰性加载

    关于惰性加载 在讲图片的惰性加载前,我们先来聊聊惰性加载.惰性加载又称为延迟加载.懒加载等,还有个好听的英文名字叫做 "lazyload".需要注意的是,惰性加载并不只是图片的专利 ...

  2. 关于图片的预加载以及延伸

    图片的预加载不难,方式有很多种,本来不打算单独写一篇文章,因为网上有很多大神写的很好,本来转载一篇相关的优质文章就好了.直到我读了一篇文章,发现图片的预加载有不少延伸知识,于是加以整理,有了这篇文章. ...

  3. 【亲测可用→防止入坑Routes】设置angular10项目异步加载、惰性加载、懒加载路由

    创建一个带路由的项目,依次执行下面每行代码 ng n RouingApp --routingcd RouingAppng g c components/firstng g c components/s ...

  4. php 图片预览原理,JavaScript_纯JS实现的批量图片预览加载功能,1.实现原理直接见代码,需要一 - phpStudy...

    纯JS实现的批量图片预览加载功能 1.实现原理直接见代码,需要一张转圈的小图片,需要预览的所有图片默认的位置全是这张小图片,滚轮滚到原图需要出现的位置时候,预览加载替换小图片.实现效果 复制代码 代码 ...

  5. Jquery背景图片的预加载

    Jquery背景图片的预加载 //定义预加载图片列表的函数(有参数)  jQuery.preloadImages = function(){   //遍历图片   for(var i = 0; i&l ...

  6. 如何使用echo.js实现图片的懒加载(整理)

    如何使用echo.js实现图片的懒加载(整理) 一.总结 一句话总结:a.在img标签中添加data-echo属性加载真实图片:<img class="loading" sr ...

  7. Angular Lazy load(延迟加载,惰性加载) 机制和 feature module 的学习笔记

    官网链接 默认情况下,NgModules 是贪婪加载的,这意味着一旦应用程序加载,所有 NgModules 也会加载,无论它们是否立即需要. 对于有很多路由的大型应用程序,可以考虑延迟加载--一种根据 ...

  8. html循环加载多个图片,两行代码实现图片碎片化加载

    今天来实现一个图片碎片化加载效果,效果如下: 我们分为 3 个步骤来实现: 定义 html 结构 拆分图片 编写动画函数 定义 html 结构 这里只需要一个 canvas 元素就可以了. id=&q ...

  9. EF Core 2.1路线图:视图、GROUP BY和惰性加载

    Entity Framework Core一直追随着初始Entity Framework的发展,并不断推陈出新.它首先推出的是对视图的支持,这听起来有些耸人听闻.在即将推出的EF Core 2.1之前 ...

最新文章

  1. 【seaborn】(1) 数据可视化,绘图风格、布局
  2. Android10.0 Binder通信原理(九)-AIDL Binder示例
  3. go与Java微服务对比_微服务架构对比-Go语言中文社区
  4. vscode setting json_win10+letex+vscode+texlive+latex workshop+sumatrapdf
  5. gb酱油和gbt酱油哪个好_都是酱油,生抽好还是味极鲜好?老板:两者差别很大,别买错了...
  6. 重读读书笔记的重要性
  7. python 抓取微博评论破亿_如果利用Python分析14亿条数据!资深程序员手把手教你!过亿级!...
  8. 读者写者问题详解 操作系统
  9. redistemplate hash 过期时间_redisTemplate的使用以及和stringRedisTemplate的区别
  10. IJCAI阿里论文 | JUMP: 一种点击和停留时长的协同预估器...
  11. JQuery快速学一(强悍的选择器)
  12. arcgis自带的python版本_arcgis10.3自带的python2.7.8怎么安装geopandas?
  13. 数据平滑处理——log1p()和exmp1()
  14. 程序员必读: 摸清Hash表的脾性
  15. GL-Currencies-Rates-Daily:Error:APP-FND-01206: This record already exists-文档 ID 292731.1
  16. 独立开发者:新手做2D手游该用哪些工具
  17. ASK调制的matlab代码
  18. murmurHash使用方法
  19. 希望所有程序员的世界里,永远没有BUG
  20. 体验篇 - Zcash

热门文章

  1. 配置EditPlus
  2. jQuery源码解析(5)—— Animation动画
  3. Mr.J-- jQuery学习笔记(六)--attrprop方法
  4. 获取时间,并将时间的空格和特殊字符去掉,作为一个变量来使用
  5. 精进:如何成为一个很厉害的人---书摘
  6. LightOJ 1096 - nth Term 矩阵快速幂
  7. CoreAnimation汇总
  8. 浅谈equals和hashcode
  9. 使用负边距创建自适应宽度的流体布局
  10. 在ie6下remove包含iframe的table所在的容器,会导致页面控件的焦点诡异丢失。