利用Intersection Observer实现图片懒加载性能优化

ntersection Observer是浏览器所提供的一个 Javascript API,用于异步的检测目标元素以及祖先或者是顶级的文档视窗的交叉状态

这句话的意思就是:

我们可以看的图片当中,绿色的 target element(目标元素),并且存在一个顶层的或者祖先的文档视窗也就是当前图片中的,灰色的 browser viewport(浏览器的视窗)

当 target element(目标元素)进行移动的时候,将会与 browser viewport(浏览器的视窗)进行交叉状态的监控,那么利用这个交叉状态的监控,我们就可以实现诸如一个懒加载无限滚动或者是与元素可见性相关的一种操作。

Intersection Observer基本概念的理解:

Intersection Observer是一个观察期,创建一个观察的对象,该对象可以观察一个或多个元素,而我们的目标元素target element 则是需要被观察的 dom元素,至于 intersection ratio 也就是交叉 其目标元素 与 其祖先或视窗 相交的一个状态,那么交叉比例也就是 intersection ratio指的是目标元素与其视窗或祖先元素相交的一个百分比。我们可以从上方图片中感受到这里面如果绿色的顶部这条线和 browser viewport 的底部是重合的,我们的交叉比例应该是0;如果是图片中当前的位置,我们的交叉比例应该接近于0.5也就是百分之五十;如果在往上走的时候,我们的交叉比例可能就是1

那么利用Intersection Observer能否去实现懒加载的性能优化呢,我们需要先确认的是:为什么会需要进行性能优化、我们原来进行图片懒加载的方式又是怎样的,我们可以通过一个实例进行相应是说明:

html 代码:

利用link进行相对应的样式引入

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="./index2.css">
</head>
<body><div><h1>图片相册</h1><img data-src="http://pic1.win4000.com/wallpaper/2018-09-19/5ba21a3006800.jpg" alt=""><img data-src="https://t7.baidu.com/it/u=1785207335,3397162108&fm=193&f=GIF" alt=""><img data-src="https://t7.baidu.com/it/u=338595665,4065109605&fm=193&f=GIF" alt=""><img data-src="https://t7.baidu.com/it/u=1732966997,2981886582&fm=193&f=GIF" alt=""><img data-src="https://t7.baidu.com/it/u=2581522032,2615939966&fm=193&f=GIF" alt=""><img data-src="https://t7.baidu.com/it/u=245883932,1750720125&fm=193&f=GIF" alt=""><img data-src="https://t7.baidu.com/it/u=3423293041,3900166648&fm=193&f=GIF" alt=""><img data-src="https://t7.baidu.com/it/u=3241434606,2550606435&fm=193&f=GIF" alt=""> <img data-src="https://t7.baidu.com/it/u=1417505637,1247476664&fm=193&f=GIF" alt=""><img data-src="https://img0.baidu.com/it/u=775184654,1087701200&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"><img data-src="https://lmg.jj20.com/up/allimg/1114/1110200ZS0/2011100ZS0-9-1200.jpg" alt=""></div></body>
<script src="./index2.js"></script>
</html>
css代码:
// 对页面中的img标签进行一个控制
img{width: 100vw;  // 宽度transform: translateX(50%);  // 横轴变化的操作(也就是位移)opacity: 0;  // 不可见transition: all 500ms;  // 动画的控制
} .fade{transform: translateX(0);  // 位移操作opacity: 1;  // 可见状态transition: all 500ms;  // 动画的操作
}
js代码:
//查询所有的img标签内容
const targets = document.querySelectorAll('img');// 监听滚动事件
window.addEventListener("scroll", (event) => {// 遍历所有的img标签targets.forEach((img) => {// 获取img标签的top值console.log("load img")const rect = img.getBoundingClientRect().top;// 如果img标签的top值小于窗口的高度if (rect <= window.innerHeight){// 获取img标签的data-src属性值const src = img.getAttribute("data-src");// 将data-src属性值赋值给src属性img.getAttribute("src", src);// 添加fade类名img.classList.add("fade");}})
})

我们可以查看一下页面:

当我们进行滚动操作的时候,将会不断的加载显示我们所需要显示的应一个图片,但是,当我们将控制台切换到console,会发现当我们滚动滚动条时,打印的信息频率异常的高,随随便便就产生了上千次的打印代码的输出操作,这也就是意味着我们的性能其实是极其的低下的,那么如何去减少滚动时对于图片懒加载显示的性能提升呢?

我们可以去考虑,当这个图片显示在这个browser viewport(浏览器的视窗),我们对其进行的是观察操作,只有在可视区里面,我们才对图片进行处理,利用的就是Intersection Observer的操作处理。

那么利用Intersection Observer进行具体功能的实现:

//查询所有的img标签内容
const targets = document.querySelectorAll('img');// 定义一个函数
const lazyload = target =>{// 进行实体对象entries,并且设置一个observer参数内容const io = new IntersectionObserver((entries,observer) =>{// 进行实体对象的循环(这个实体对象便是我们之后的图片)entries.forEach((entry)=>{  // entry:每一个实体对象console.log("load img")// 当图片实例内容进行到我们的观察区时(也就是交叉的一种状态)if(entry.isIntersecting){ const img = entry.target  // 设置一个图片,便是target目标const src = img.getAttribute("data-src")  // 通过data-src这个自定义数据内容进行来源数据的获取属性img.setAttribute("src",src);  // 设置图片路径img.classList.add("fade")  // 添加动画效果observer.disconnect();  // 将观察的内容进行取消连接的一个状态}})})io.observe(target)  // 通过io进行具体的observe观察图片内容
}targets.forEach(lazyload);  // 最终对图片(获取到的图片数组)进行循环,调用的则是lazyload 自定义函数

 此时,我们再进行滚动下来操作时,console打印的次数只有十几次:

而使用scroll监听滚动时,有成千次的执行,所以我们可以利用Intersection Observer进行一个图片懒加载性能优化的一个处理。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/674054.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

强化学习 | 基于 Q-Learning 算法解决 Treasure on Right 游戏

Hi&#xff0c;大家好&#xff0c;我是半亩花海。在本篇技术博客中&#xff0c;我们将探讨如何使用 Q-Learning 算法来解决 Treasure on Right 游戏&#xff0c;实现一个简单的强化学习。 一、游戏背景 Treasure on Right 游戏——一个简单的命令行寻宝游戏&#xff0c;是一个…

删除和清空Hive外部表数据

外部表和内部表区别 未被external修饰的是内部表&#xff08;managed table&#xff09;&#xff0c;被external修饰的为外部表&#xff08;external table&#xff09;&#xff1b; 区别&#xff1a; 内部表数据由Hive自身管理&#xff0c;外部表数据由HDFS管理&#xff1b; …

SpringBoot和SpringMVC

目录 一、springboot项目 &#xff08;1&#xff09;创建springboot项目 &#xff08;2&#xff09;目录介绍 &#xff08;3&#xff09;项目启动 &#xff08;4&#xff09;运行一个程序 &#xff08;5&#xff09;通过其他方式创建和运行springboot项目 二、SpringMVC…

高可用 k8s 1.29 一键安装脚本, 丝滑至极

博客原文 文章目录 集群配置配置清单集群规划集群网络规划 环境初始化主机配置 配置高可用ApiServer安装 nginx安装 Keepalived 安装脚本需要魔法的脚本不需要魔法的脚本配置自动补全加入其余节点 验证集群 集群配置 配置清单 OS&#xff1a; ubuntu 20.04kubernetes&#xf…

【Scala】1. 变量和数据类型

1. 变量和数据类型 1.1 for begining —— hello world 新建hello.scala文件&#xff0c;注意object名字与文件名一致。 object hello { def main(args:Array[String]): Unit { println("hello world!") } }运行后打印结果如下&#xff1a; hello world!Pr…

Golang 并发 生产者消费者模式

Golang 并发 生产者消费者模式 生产者-消费者模式能够带来的好处 生产者消费者模式是一种常见的并发编程模式&#xff0c;用于解决生产者和消费者之间的数据传递和处理问题。在该模式中&#xff0c;生产者负责生成数据&#xff08;生产&#xff09;&#xff0c;而消费者负责处…

【射影几何13 】梅氏定理和塞瓦定理探讨

梅氏定理和塞瓦定理 目录 一、说明二、梅涅劳斯&#xff08;Menelaus&#xff09;定理三、塞瓦(Giovanni Ceva&#xff09;定理四、塞瓦点的推广4.1 共线定理4.2 三角形外的塞瓦点 一、说明 在射影几何中&#xff0c;梅涅劳斯&#xff08;Menelaus&#xff09;定理和塞瓦定理是…

最大子数组和[中等]

一、题目 给定一个长度为n的环形整数数组nums&#xff0c;返回nums的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c;nums[i]的下一个元素是nums[(i 1) % n]&#xff0c;nums[i]的前一个元素是nums[(i - 1 n) % n]。 子数…

论文封面下划线总是对不齐,这3步你肯定没做!

论文封面 在写论文时&#xff0c;总会遇到论文封面下划线对不齐&#xff0c;学会下面这三招轻松搞定封面。 解决方法 ①选中文字&#xff0c;点击“插入”&#xff0c;选择“表格”&#xff0c;找到“文本转化为表格”。列数为2&#xff0c;文字分割位置选空格&#xff0c;设置…

第21讲:动态内存管理

1.为什么要有动态内存分配 2.malloc和free 3.calloc 4.realloc 5.笔试题 6.总结c/c中程序内存区域划分 1.为什么要有动态内存分配 为了调整申请的空间大小&#xff0c;使程序员可以申请和释放空间&#xff0c;提高程序的灵活性 2.malloc和free 作用&#xff1a;分配一块…

python将.db数据库文件转成Excel文档

python实现.db数据库转Excel 程序实现 上一篇文章程序实现以下功能&#xff1a; 1.读取一个Excel文件,文件名通过函数传参数传入 2.将文件读取的内容保存到一个数据库文件中 3.数据库的文件名以传入的Excel文件的文件名命名 4.将excel文件的工作簿的名字作为数据库的表单名 5…

apache_exporter安装说明

Apache Exporter 问题描述 需要监控apache服务&#xff0c;部署了apache_exporter&#xff0c;对过程进行一下记录。 源码参见apache_exporter ①下载 https://github.com/Lusitaniae/apache_exporter/releases②解压缩 tar -xzvf apache_exporter-0.7.0.linux-amd64.tar…

深入了解Redis:选择适用于你的场景的持久化方案

自然语言处理的发展 文章目录 自然语言处理的发展强烈推荐前言&#xff1a;Redis提供了几种主要的持久化方案&#xff1a;RDB快照持久化&#xff1a;工作原理&#xff1a; AOF日志文件持久化&#xff1a;混合持久化&#xff1a; 总结强烈推荐专栏集锦写在最后 强烈推荐 前些天…

相机图像质量研究(7)常见问题总结:光学结构对成像的影响--镜片固化

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

戴上HAUWEI WATCH GT 4,解锁龙年新玩法

春节将至&#xff0c;华为WATCH GT 4作为一款颜值和实力并存的手表&#xff0c;能为节日增添了不少趣味和便利。无论你是钟情于龙年表盘或定制属于自己的表盘&#xff0c;还是过年用来抢红包或远程操控手机拍全家福等等&#xff0c;它都能成为你的“玩伴”。接下来&#xff0c;…

C语言 服务器编程-日志系统

日志系统的实现 引言最简单的日志类 demo按天日志分类和超行日志分类日志信息分级同步和异步两种写入方式 引言 日志系统是通过文件来记录项目的 调试信息&#xff0c;运行状态&#xff0c;访问记录&#xff0c;产生的警告和错误的一个系统&#xff0c;是项目中非常重要的一部…

JUnit 5 注解总结与解析

前言 大家好&#xff0c;我是chowley&#xff0c;通过前篇的JUnit实践&#xff0c;我对这个框架产生了好奇&#xff0c;除了断言判断&#xff0c;它还有哪些用处呢&#xff1f;下面来总结一下它的常见注解及作用。 正文 在Java单元测试中&#xff0c;JUnit是一种常用的测试框…

linux互斥锁:递归锁,非递归锁用法详解

在实际的项目中经常涉及到共享资源&#xff0c;共享资源被多个线程访问会出现竞争现象&#xff1b;为了解决竞争和保护共享资源常用的机制之一就是互斥锁&#xff01; 互斥锁又分为递归锁和非递归锁&#xff0c;互斥锁默认是非递归锁&#xff0c;也是我们常用的上锁方式。那么什…

零基础学Python之整合MySQL

Python 标准数据库接口为 Python DB-API&#xff0c;Python DB-API为开发人员提供了数据库应用编程接口。 不同的数据库你需要下载不同的DB API模块&#xff0c;例如你需要访问Oracle数据库和Mysql数据&#xff0c;你需要下载Oracle和MySQL数据库模块。 DB-API 是一个规范. 它…

【51单片机】要实现动静态数码管,你首先需要知道这些【数码管项目前置知识】

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 本章节内容为【实现动静态数码管】项目的第一个模块完整章节&#xff1a;传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持…