背景

图片懒加载是针对图片加载时机的一种优化,在一些图片量比较大的网站(比如电商网站首页,或者团购网站、小游戏首页等),如果我们尝试在用户打开页面的时候,就把所有的图片资源加载完毕,那么很可能会造成白屏、卡顿等现象,因为图片真的太多了,一口气处理这么多任务,浏览器做不到啊!

懒加载是为了让浏览器只加载可视区内的图片,可视区外的大量图片不进行加载,当页面滚动到后面去的时候再进行加载。这样做有很多好处可以增加首屏加载的速度,毕竟,用户点开页面的瞬间,呈现给他的只是首屏,我们只要把首屏的资源图片加载处理就可以了,至于下面的图片,当用户下滑当当前位置的时候,在加载出来也是没问题的,对于性能压力也小了,用户体验也没有变差。

解答

图片懒加载的原理就是需要知道图片是否在可视区内了,当图片到达可视区内就需要去请求对应的图片加载出来

页面中的img标签一般如下写

<img class="lazyload" src="placeholder.jpg" data-src="real_image.jpg" />

其中src首先赋值一个占位的图片,一般是一个很小的图片,进行占位,src是实际需要展示的图片,原理就是当图片在可视区内的时候将src的图片选渲染出来即可。

1、原生实现

Chrome 76 将原生支持图片的惰性加载,支持对img和iframe进行延迟加载,只需要将loading属性设置为lazy即可。

<img src="celebration.jpg" loading="lazy" alt="..." />
<iframe src="video-player.html" loading="lazy"></iframe>

原生实现的好处是,不需要任何脚本,纯原生HTML即可,简单方便,支持多种属性

  • lazy:对资源进行延迟加载。
  • eager:立即加载资源。
  • auto:浏览器自行判断决定是否延迟加载资源。

原生的坏处就是在于浏览器的支持率不是很高,将来肯定是非常好的。

我们知道由于浏览器的支持率不是很好,上面的方案固然很好,但是使用的并不是很多,所以下面介绍几种更加常见的懒加载方案。

2、Element.getBoundingClientRect()

getBoundingClientRect返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。

有了这个API后我们很同意获取图片的top值,当top值小于可视区的高度的时候就可以任何图片进入了可视区,直接加载图片即可

element.getBoundingClientRect().top < document.documentElement.clientHeight

由于需要在滚动的时候去监听图片的位置,所以我们需要使用到window.onscroll事件,我们在事件内部处理相关的逻辑即可。

3、通过相对计算获取元素位置

  1. 通过document.documentElement.clientHeight获取屏幕可视窗口高度。
  2. 通过element.offsetTop获取元素相对于文档顶部的距离。
  3. 通过document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离。 然后判断2-3<1是否成立,如果成立,元素就在可视区域内。
element.offsetTop -  document.documentElement.scrollTop < document.documentElement.clientHeight

此方法也需要在滚动的时候去监听图片的位置,所以我们需要使用到window.onscroll事件,我们在事件内部处理相关的逻辑即可。

4、使用IntersectionObserver

const observer = new IntersectionObserver(callback, observerConfig)const imgList = document.querySelectorAll(".lazyload");
const observer = new IntersectionObserver(entries => {entries.forEach(item => {if (item.isIntersecting) {item.target.src = item.target.dataset.origin; // 判断在可视区了,把data-origin的值放到srcobserver.unobserve(item.target); // 已经加载过的图片停止进行监听}});
});
imgList.forEach(item => observer.observe(item));

补充

1、优化

由于上面某些情况是需要使用到window.scroll事件的,所以我们可以增加节流来减少事件处理函数的调用次数。 假设我们判断是否可视区逻辑为函数loadImage那么我们可以如下处理。

window.onscroll = throttle(loadImage, 500)

2、拓展

上面后续三种方法不仅仅可以使用在图片的懒加载上面,其实所有可以懒加载的地方都可以通过这种方式进行判断,比如列表分页加载,我们可以通过这种方式进行判断是否需要进行下一页的加载,比如我们需要埋曝光埋点的时候,可以通过这种方法判断元素是否曝光,进行埋点事件的触发。

document引用图片的src属性能干嘛_如何实现图片懒加载相关推荐

  1. 图片预加载与图片懒加载

    图片预加载与图片懒加载 图片预加载 图片预加载主要是针对非icon类图片. 加载快,有良好的用户体验. 提前加载图片,当用户需要查看时可直接从本地缓存中渲染.可能因为图片很大,浏览器显示出它会用很长的 ...

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

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

  3. 实现图片懒加载的5种方式

    目录 1.懒加载介绍 2.实现懒加载技术的方案 3.具体实现代码 1.懒加载介绍 当页面需要展示大量图片时,如果一次性渲染所有图片,会向服务器发出大量请求,导致服务器响应慢,出现页面卡顿或崩溃等问题. ...

  4. load方法引入本地html报错,分享基于plus.downloader的图片懒加载功能,支持本地缓存v1.1.0...

    今天试用了下hello mui上的图片懒加载功能,发现有些地方还无法满足我的需求,ajax动态加载的时候无法实现懒加载. 然后又看了下36kr的示例,因为代码关系实在太多了,耦合度比较高,遂自己动手写 ...

  5. WEB前端 实现图片懒加载 echo.js

    echo.js是一个轻小的图片懒加载js插件,在使用过程中很多朋友可能是直接自定义一张占位图片,可能会造成图片的变形等.其实这并不是最佳的解决方案.下面给大家介绍另一种方法,简单的控制下css,实现l ...

  6. layui图片懒加载-loading占位图

    前言 使用layui的图片懒加载,发现未加载的图片没有loading占位图,显示的是裂图,看着不是很好.找了一些解决方法我统一记录一下. layui图片懒加载使用方法 layui.use('flow' ...

  7. html data-src和src的区别,img 的data-src 属性实现懒加载

    一.什么是图片懒加载? 当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次),当图片出现在浏览器的可视区域内时,才设置图片真正的路径 ...

  8. JQuery实现网页图片懒加载

    使用img标签加载图片,在网页上显示图片,这里就简单的设置一下样式了,主要目的是展示图片的不同加载方式. 1.普通实现方式 普通的实现方式就是不做任何处理,需要使用到图片时就去加载图片,这些图片一般存 ...

  9. 图片懒加载(lazyload)的几种方式

    背景 当页面中有很多图片时,全部加载需要很多时间,而且会消耗很多渲染资源,为了解决这个问题,加强用户体验,我们先将看得到的区域中的图片加载,也就是 可视化区域 加载,剩余部分等之后再加载. 原理   ...

最新文章

  1. python isodd()判断奇偶_位运算(1的个数;2.判断奇偶)
  2. SAP库存表之间的逻辑关系
  3. 计算机网络系统--Microsoft Lync 与 腾讯通RTX 对比(转载)
  4. python 命名空间冲突_通过修改命名空间绕过pb冲突
  5. qt高亮快捷键_QtCreator中常用快捷键总结
  6. sqlserver迁移数据到mysql_SQLServer数据库之将ABP的数据库从SQLSERVER迁移到MySql
  7. c语言程序设计学生程序查询,《c语言程序设计报告-学生信息管理系统》.doc
  8. java原生的ajax怎么写_原生Ajax代码实现
  9. OpenStack精华问答 | OpenStack 网络中 OpenFlow 规则的作用是什么?
  10. win8学习--------计时器
  11. 微服务升级_SpringCloud Alibaba工作笔记0017---Nacos之服务消费者注册和负载
  12. C#的变量、数据类型转换、转义符
  13. nginx linux 部署web项目名,Linux部署web项目配置Nginx
  14. 利用FGSM实现对抗样本攻击
  15. base64原理与实现
  16. 使用 Infiniband 实现 RDMA !IB卡介绍!下载IB 驱动 !lspci | grep Mell 查看 IB卡!
  17. win7电脑蓝屏怎么办
  18. prisma1.0实践
  19. java如何用雪花算法批量生成唯一编码(保证位数不过长)?
  20. [gdc13]古墓丽影DirectX11技术

热门文章

  1. EJS学习(一)之特性、安装、工作原理
  2. OS之进程管理 --- 死锁
  3. 设置tomcat 编译文件位置【转】
  4. 使用SCOM常用的一些ManagementPack
  5. Deployer 的使用
  6. vue深究第一弹:computed与watch的异同
  7. FJOI2018二试游记
  8. BZOJ 3195: [Jxoi2012]奇怪的道路 | 状压DP
  9. xss原理、攻击方式与防御
  10. BZOJ 3309 DZY Loves Math