利用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.hqwc.cn/news/460304.html

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

相关文章

百度员工:纠结!31岁,我年薪78w,老婆50w,两人在深圳同一家公司。武汉有房,现在有机会回去,但会降薪15%左右。...

上一篇&#xff1a;《繁花》里宝总成功的秘诀&#xff0c;句句真理&#xff01; 深圳的一名31岁的百度员工&#xff0c;拥有高薪和舒适的生活&#xff0c;与妻子过着看似完美的日子。当他们准备迎接家庭的新阶段时&#xff0c;面临一个艰难的抉择&#xff1a;是在深圳继续追求事…

性能篇:如何解决高并发下 I/O 瓶颈?

我们可以有效地解决高并发下I/O瓶颈的问题&#xff0c;提升系统的性能。当然&#xff0c;实际场景中的优化可能涉及到更多的细节和技术&#xff0c;但希望这篇文章能为大家提供一些思路和方法。​ 引言 大家好&#xff0c;我是小米&#xff01;今天我们来聊一个在高并发场景…

2021年通信工程师初级 实务 真题

文章目录 一、第1章 现代通信网概述&#xff0c;通信网的定义。第10章 通信业务&#xff0c;普遍服务原则10.2.4 通信行业的发展趋势&#xff08;六化&#xff09; 二、第2章 传输网SDH帧结构SDH线路保护倒换&#xff0c;“11 保护”和“1:1保护”波长值λc/f&#xff0c;中心频…

Docker-Learn(三)创建镜像Docker(换源)

根据之前的内容基础&#xff0c;本小点的内容主要涉及到的内容是比较重要的文本Dockerfile 1. 编辑Dockerfile 启动命令行终端&#xff08;在自己的工作空间当中&#xff09;,创建和编辑Dockerfile。 vim Dockerfile然后写入以下内容 # 使用一个基础镜像 FROM ubuntu:late…

Verilog刷题笔记24

题目&#xff1a; Verilog has a ternary conditional operator ( ? : ) much like C: (condition ? if_true : if_false) This can be used to choose one of two values based on condition (a mux!) on one line, without using an if-then inside a combinational alwa…

vulnhub中Beelzebub靶机

渗透思路 一.信息收集1.网段探测2.端口探测3.常见漏洞扫描4.目录扫描5.web页面分析 二.渗透继续目录扫描ssh连接提权提权&#xff0c;flag 一.信息收集 1.网段探测 ┌──(root㉿kali)-[~] └─# nmap -Pn 192.168.0.0/24 --min-rate 10000 Starting …

【MySQL】学习和总结DCL的权限控制

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Bl9kYeLf8GfpdQgL {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

『运维备忘录』之 Ansible 自动化运维工具

一、简介 Ansible是基于Python开发&#xff0c;集合了众多运维工具&#xff08;puppet、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置、批量程序部署、批量运行命令等功能的自动化运维工具&#xff0c;广泛用于配置管理、应用部署以及任务协…

应用ANN+SMOTE+Keras Tuner算法进行信用卡交易欺诈侦测

目录 SMOTE&#xff1a; ANN&#xff1a;ANN(MLP) 三种预测-CSDN博客 Keras Tuner&#xff1a;CNN应用Keras Tuner寻找最佳Hidden Layers层数和神经元数量-CSDN博客 数据&#xff1a; 建模&#xff1a; SMOTE Sampling&#xff1a; Keras Tuner&#xff1a; SMOTE&…

计网——运输层、端口号

目录 运输层 1 进程之间的通信 运输层的作用 屏蔽作用 可靠信道与不可靠信道 2 运输层的两个主要协议 3 运输层的端口 端口号 (protocol port number) 软件端口 硬件端口 TCP/IP 运输层端口的标志 两大类、三种类型的端口 常用的熟知端口 运输层 1 进程之间的通信 …

十二、常见算法和Lambda——五道经典算法题

十二、常见算法和Lambda——经典算法题 练习一&#xff08;按照要求进行排序&#xff09;练习2:&#xff08;不死神兔&#xff09;练习3&#xff08;猴子吃桃子&#xff09;练习4&#xff08;爬楼梯&#xff09; 练习一&#xff08;按照要求进行排序&#xff09; 定义数组并存…

Spinnaker多云持续交付平台: 部署Minio存储服务

目录 一、实验 1.环境 2.K8S storage节点部署NFS 3.K8S 动态创建PV 4.K8S master节点部署HELM3 4.K8S master节点部署Minio存储服务&#xff08;第一种方式安装&#xff09; 5.Minio客户端安装MC命令 6.K8S master节点使用Docker 部署Minio存储服务&#xff08;第二种方…