详解前端性能优化之原生JS实现图片懒加载效果(通过IntersectionObserver内置构造函数实现)

2023-10-26

        相信你作为一名用户,使用一款app,在首次打开页面时卡顿超过3秒时就会有退出的想法。所以我们在日常开发中,通常需要使用一些手段实现对性能的优化,来使得页面加载更快,用户体验更好。这其中有许多方式,其中最常用的无非是按需加载了,今天就带大家重点且详细的讲一下原生JS实现的图片懒加载。

图片懒加载的两种实现方式:  

       窗口滚动事件监听图片位置(效果有但不好用)

       IntersectionObserver构造函数(最常用且非常好用)


 注意:这两种方式都需要在JS操作前,将<img>标签中的src属性本该对应的值存在自定义的一个属性(比如data-src)中,因为最开始我们不需要让请求到的图片资源直接加载出来,只是先将其随便存在一个属性当中,在后续的懒加载操作中再将其修改为src。比如以下这种写法:

<img data-src="./img_test/xn3.jpg" width="400" height="800" />

窗口滚动事件监听图片位置

      实现思路:先获取所有的img标签,然后用window的scroll滚动监听事件对所有image图片进行监听,在浏览器滚动过程中发现如果该图片距离浏览器可视窗口顶部的距离小于浏览器高度,也就是在页面中能看到该图片时触发回调操作,先获取到data-src中的地址,然后把它赋值给真实的src路径使其能够加载出来。具体代码如下:

window.addEventListener("scroll", (e) => { // 为window加入滚动监听事件
  IMGS.forEach(ele => { // 遍历获取到的img标签,为每个都添加监听
      const imgTop = ele.getBoundingClientRect().top; // 获取每一个img图片上方距离浏览器顶部的距离
      // 判断图片上方距离浏览器可视窗口顶部的距离是否小于浏览器高度
      if (imgTop < window.innerHeight) { // 如果小于的话, 说明图片已经在页面中能够被看到, 那么获取
          const data_url = ele.getAttribute("data-src"); // 获取data-src中存放的真实图片url地址
          ele.setAttribute("src", data_url); // 将真实图片url地址给到src路径中
      }
  })
})

这个效果能够虽然能够实现图片的懒加载功能,但它的弊端却又非常多。首先,它是通过滚动监听触发,如果页面顶部有img图片的话在首次加载时如果不去滚动就不会去显示了,还有就是我们在window做监听在图片全部加载完毕后还需要关闭监听事件,这样一想好像有些麻烦了,那么我们就阔以使用第二种方式来解决 --- 通过IntersectionObserver构造函数实现。

 IntersectionObserver构造函数

      IntersectionObserver是浏览器为我们提供的一种构造函数,也就是可以直接拿来使用的,不过前提是浏览器能够支持,部分浏览器版本并不兼容。IntersectionObserver的字面意思就是交叉观察,也就是可以自定义一个目标元素来进行观察,它会和浏览器可视窗口产生交叉区域(也就是当图片在浏览器窗口能够被看到时和不能被看到时),可以在交叉区域发生时来定义我们需要做的事情。

      因为IntersectionObserver是一个构造函数,所以我们需要new一实例,这个构造函数也会接收两个参数,第一个是一个函数,第二个是配置参数,当然这里我们只需要用第一个参数(构造函数)就可以了,这个构造函数也会接收到一个默认参数entries,entries是一个数组,里面会存储着所有被观察的节点相较于浏览器可视窗口的一系列信息,其中entries里面每一个子元素(也就是某个被观察的节点)都有一个 isIntersecting 属性代表该节点是否在浏览器中可以被看到。

如下


看下打印结果:


对于Observer实例,我们可以调用 observer() 和 unobserve() 两个方法来进行我们的操作。

其中:

      Observer.observer() 用于加入观察的节点。

      Observer.unobserver() 用于停止观察节点。

     当设置Observer.observer()后,所观察的节点会有两次触发时机。分别是该节点在浏览器可见时和不可见时会触发,我们就可以在这里做我们想做的事情。具体实现思路就是在节点可见时将图片 data-src 中的路径给真实的 src,然后使用Observer.unobserver()来停止观察。

代码如下:

const IMGS = document.querySelectorAll("img"); // 获取所有图片
const callback = entries => { // 设置构造函数中接收到的参数中的操作事项
  entries.forEach(enntry => { // 因为entries里面放着所有被观察的节点,所有需要遍历判断
      if (enntry.isIntersecting) { // 判断当前节点是否在可视区域能被看到
          const image = enntry.target; // 通过事件对象拿到这个元素
          const data_url = image.getAttribute("data-src"); // 获取该元素data-src中存放的路径
          image.setAttribute("src", data_url); // 赋值给真实路径
          Observer.unobserve(image); // 停止观察
      }
  })
}
const Observer = new IntersectionObserver(callback); // 生成实例
IMGS.forEach(img => Observer.observe(img)) // 通过遍历对所有Img元素都进行观察

看下在浏览器中的具体效果吧(这里我开了3G慢网和禁止缓存来进行测试)


 总结:通过IntersectionObserver构造函数实现图片懒加载相较于滚动监听好的太多了,首先浏览器已经为我们提供了能够停止观察的api。同时,因为是观察行为,所以只要图片出现在了浏览器可视窗口中就会被触发api,我们就不需要再去考虑滚动的问题了,十分方便。当然,学会了IntersectionObserver,我们还可以去进行其他需要优化性能的操作。

所以,学到就是赚到,快去试试吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

详解前端性能优化之原生JS实现图片懒加载效果(通过IntersectionObserver内置构造函数实现) 的相关文章

随机推荐

  • Python中的三引号''' '''的用法

    链接 https blog csdn net GreenHandCGL article details 79703863
  • ERP仓库管理的操作与设计--开源软件诞生20

    赤龙ERP库房管理讲解 第20篇 用日志记录 开源软件 的诞生 点亮星标 祈盼着一个鼓励 博主开源地址 码云 https gitee com redragon redragon erp GitHub https github com red
  • minkwindow安装

    装库要记住三件事 官网 csdn 耐心 装库太慢就边看剧边装 不要影响心态 首先上官网 GitHub NVIDIA MinkowskiEngine Minkowski Engine is an auto diff neural networ
  • 国产超低功耗华大单片机HC32L136开发板上手入门

    今天介绍下国产超低功耗华大单片机HC32L136开发板上手后的入门操作 开发板可以在华大MCU应用交流群 164973950 免费申请 HC32L136开发板 如下图所示 分为板载调试模块 左半部分 和MCU开发电路 右半部分 二者中间通过
  • 当你的sklearn用不了mean_absolute_percentage_error函数

    今天将一份写好的python机器学习程序换了个电脑跑的时候 出现了如下报错 ImportError cannot import name mean absolute percentage error from sklearn metrics
  • 解决K8s安装中节点初始化时 [kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ 问题.

    问题描述 安装K8s时 在节点初始化过程中出现 kubelet check The HTTP call equal to curl sSL http localhost 10248 healthz failed with error Get
  • WINDOWS 10 设置WSL 2

    确保已安装 WSL 可以在此处找到相关说明 并且运行的是 Windows 10内部版本 18917或更高版本 可以通过在 PowerShell 中运行以下命令来执行此操作 PowerShell dism exe online enable
  • 分布式深度学习part1:神经网络的分布式训练

    这篇文章是关于神经网络分布式训练的三部系列文章中的第一篇 在第1部中 我们将了解如何通过GPU上的分布式计算显著地加速深度学习模型的训练 并讨论一些挑战并调查当前关于该主题的研究 我们还将考虑神经网络的分布式训练是否适用于特定用例 介绍 在
  • stm32关于通用定时器的周期、频率计算公式

    以下内容针对正点原子的定时器中断实验 定时器时基单元包含 计数器寄存器 TIMx CNT 预分频器寄存器 TIMx PSC 该寄存器用设置对时钟进行分频 然后提供给计数器 作为计数器的时钟 自动装载寄存器 TIMx ARR 定时器的时钟来源
  • 【适合小白】开发一个区块链应用

    前言 本篇教程是小编基于FISCO BCOS官网的教程撰写的 有不明白的地方也可以去官网上的教程看看 在开发区块链应用之前 首先得完成搭建第一个区块链应用 目的是为了搭建节点跟启动控制台 1 了解应用需求 区块链天然具有防篡改 可追溯等特性
  • MQTT协议学习

    MQTT协议是目前物联网最主要的协议 它的设计主要是运用于 低带宽 低网速 差网络环境能够保证数据的正常传输 MQTT协议基于TCP IP协议 运用订阅发布模式 解除应用之间的耦合关系 客户端与客户端之间只需要知道服务器位置 就可以传输数据
  • Github管理项目代码相关git命令

    1 Git global setup git config global user name username git config global user email user email 2 Create a new repositor
  • .classpath .project ch2.iml这三个文件如何理解?

    这三个文件通常出现在Java开发中使用的集成开发环境 IDE 项目中 如Eclipse或IntelliJ IDEA 它们在项目的组织和配置方面发挥着重要的作用 classpath 文件 classpath 是 Eclipse 项目的配置文件
  • Wireshark使用小心得

    Wireshark工作使用小结 基本概念 wireshark是个开源的好用软件 用来分析数据包 数据包 通常就是四层信息 物理层数据帧 数据链路层以太帧头部 网络层IP包头部 传输层TCP包头部 最后就是应用层信息 基础功能使用 打开软件界
  • 范数介绍及C++/OpenCV/Eigen的三种实现

    有时我们需要衡量一个向量的大小 在机器学习中 我们经常使用被称为范数 norm 的函数衡量向量大小 形式上 Lp范数定义如下 范数 包括Lp范数 是将向量映射到非负值的函数 直观上来说 向量x的范数衡量从原点到点x的距离 更严格地说 范数是
  • 失业的程序员(五):商战之前

    本系列前章 失业的程序员 一 二 三 四 一 关于裸奔 早几年出现了很多新名词 如裸婚 蜗居 蚁族 而像我们这种没背景 没后台 没资金的程序员创业那简直可以称为裸奔 创业是否成功的标准实在太多 不能只拿钱来衡量因为很多人会说你铜臭 不能只拿
  • MYSQL的存储过程

    存储过程 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合 调用存储过程可以简化应用开发人员的很多工作 减少数据在数据库和应用服务器之间的传输 对于提高数据处理的效率是有好处的 存储过程思想上很简单 就是数据库 SQL 语言
  • IAR编译器问题的总结

    之前做项目都是用keil编译器比较多 也基本上用得很顺手 但是最近又开始用IAR编译器 结果这次真是被它折磨得快要崩溃 现在把问题总结如下 IAR编译器版本 IAR2 10 4 IAR编译器默认的优化设置一定要注意 这个是之前做的一个项目
  • Kotlin协程源码简单聊一聊,浅浅看看表层

    今日科技快讯 近日 经历了一次停办 两次规模严重缩水之后 2023年世界移动通信大会 MWC 终于再现往日盛况 有来自200多个国家和地区的2000多家厂商参加 并在此次展会上发布了最新的产品与科技 仅中国就有100余家厂商参展 每年的MW
  • 详解前端性能优化之原生JS实现图片懒加载效果(通过IntersectionObserver内置构造函数实现)

    相信你作为一名用户 使用一款app 在首次打开页面时卡顿超过3秒时就会有退出的想法 所以我们在日常开发中 通常需要使用一些手段实现对性能的优化 来使得页面加载更快 用户体验更好 这其中有许多方式 其中最常用的无非是按需加载了 今天就带大家重