如何实现图片懒加载,原生 + React 实现方式

前言

有时候列表存在许多图片,那么一次性加载会阻塞 http 请求,为了避免在可视窗口之外的元素进行不必要的图片加载,可以尝试使用懒加载进行优化。懒加载可以显著提高页面加载性能,特别是当页面包含大量图片时。为了实现延迟加载图片(也称为懒加载),可以使用 JavaScript 和 Intersection Observer API。

实现

步骤

  1. HTML 结构:为每个图片元素设置一个占位符,并使用 data-src 属性存储实际的图片 URL。
  2. CSS 样式:设置图片占位符的样式。
  3. JavaScript:使用 Intersection Observer API 监控图片元素,当图片元素进入视口时,加载实际的图片。

代码示例

HTML 结构
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Lazy Load Images</title><style>.placeholder {width: 100%;height: 200px;background-color: #f0f0f0;display: flex;align-items: center;justify-content: center;color: #ccc;}</style>
</head>
<body><h1>Lazy Load Images Example</h1><div class="image-container"><img class="lazy" data-src="image1.jpg" alt="Image 1" class="placeholder"><img class="lazy" data-src="image2.jpg" alt="Image 2" class="placeholder"><img class="lazy" data-src="image3.jpg" alt="Image 3" class="placeholder"><!-- 添加更多图片 --></div><script>document.addEventListener("DOMContentLoaded", function() {const lazyImages = document.querySelectorAll('img.lazy');if ('IntersectionObserver' in window) {const lazyImageObserver = new IntersectionObserver(function(entries, observer) {entries.forEach(function(entry) {if (entry.isIntersecting) {const lazyImage = entry.target;lazyImage.src = lazyImage.dataset.src;lazyImage.classList.remove('lazy');lazyImageObserver.unobserve(lazyImage);}});});lazyImages.forEach(function(lazyImage) {lazyImageObserver.observe(lazyImage);});} else {// Fallback for browsers that do not support IntersectionObserverlet lazyLoadThrottleTimeout;function lazyLoad() {if (lazyLoadThrottleTimeout) {clearTimeout(lazyLoadThrottleTimeout);}lazyLoadThrottleTimeout = setTimeout(function() {const scrollTop = window.pageYOffset;lazyImages.forEach(function(img) {if (img.offsetTop < (window.innerHeight + scrollTop)) {img.src = img.dataset.src;img.classList.remove('lazy');}});if (lazyImages.length == 0) {document.removeEventListener("scroll", lazyLoad);window.removeEventListener("resize", lazyLoad);window.removeEventListener("orientationChange", lazyLoad);}}, 20);}document.addEventListener("scroll", lazyLoad);window.addEventListener("resize", lazyLoad);window.addEventListener("orientationChange", lazyLoad);}});</script>
</body>
</html>
解释
  1. HTML 结构
    • 使用 data-src 属性存储实际的图片 URL。
    • 使用 class="lazy" 标记需要懒加载的图片。
  2. CSS 样式
    • 设置图片占位符的样式,确保在图片加载前显示占位符。
  3. JavaScript
    • 使用 IntersectionObserver 监控图片元素,当图片元素进入视口时,加载实际的图片。
    • 如果浏览器不支持 IntersectionObserver,使用滚动事件和节流函数实现懒加载。

React 代码实例

代码结构
  1. 创建 React 组件
import React, { useEffect, useRef } from 'react';
import './App.css';const LazyImage = ({ src, alt }) => {const imgRef = useRef();useEffect(() => {const imgElement = imgRef.current;const handleIntersection = (entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {const lazyImage = entry.target;lazyImage.src = lazyImage.dataset.src;lazyImage.classList.remove('lazy');observer.unobserve(lazyImage);}});};const observer = new IntersectionObserver(handleIntersection, {root: null, // 使用视口作为根rootMargin: '0px',threshold: 0.1 // 当至少 10% 的图片进入视口时触发});if (imgElement) {observer.observe(imgElement);}return () => {if (imgElement) {observer.unobserve(imgElement);}};}, []);return <img ref={imgRef} data-src={src} alt={alt} className="lazy placeholder" />;
};const App = () => {return (<div className="App"><h1>Lazy Load Images Example</h1><div className="image-container"><LazyImage src="https://via.placeholder.com/300" alt="Image 1" /><LazyImage src="https://via.placeholder.com/300" alt="Image 2" /><LazyImage src="https://via.placeholder.com/300" alt="Image 3" />{/* 添加更多图片 */}</div></div>);
};export default App;
  1. 添加 CSS 样式
    在 App.css 文件中添加以下样式:
.placeholder {width: 100%;height: 200px;background-color: #f0f0f0;display: flex;align-items: center;justify-content: center;color: #ccc;
}
解释
  1. LazyImage 组件
    • 使用 useRef 获取图片元素的引用。
    • 使用 useEffect 在组件挂载时创建 IntersectionObserver 实例,并监控图片元素。
    • 当图片元素进入视口时,加载实际的图片,并取消对该图片元素的监控。
  2. App 组件
    • 渲染多个 LazyImage 组件,每个组件对应一张需要懒加载的图片。
  3. CSS 样式
    • 设置图片占位符的样式,确保在图片加载前显示占位符。
调试步骤
  1. 检查图片元素是否被正确观察
    • 在 useEffect 中添加 console.log(imgElement),确保图片元素被正确获取。
  2. 检查 IntersectionObserver 的回调
    • 在 handleIntersection 函数中添加 console.log(entries),确保回调函数被正确调用。
  3. 检查图片元素是否进入视口
    • 确保页面布局正确,图片元素确实进入了视口。

兼容性

  • IntersectionObserver 是现代浏览器支持的 API,如果需要兼容旧版浏览器,可以使用滚动事件和节流函数作为回退方案。

这样,当用户滚动页面时,只有进入视口的图片才会被加载,从而提高页面的加载性能。

总结

但这样不可避免的会存在一定视觉效果上的体验缺失,在页面滚动特别快速时,由于浏览器来不及绘制刚刚进入视图的元素,便会导致出现短暂的白屏现象。这便需要在开发过程中,去做出一定地取舍。

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

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

相关文章

TS 项目中给常用的路径定义一个别名 tsconfig.json

TS 项目中给常用的路径定义一个别名 tsconfig.json 在 TS 项目中&#xff0c;可以定义一些自定义的别名&#xff0c;来取代经常需要引用的一些文件路径。 比如 Vue 项目中你可以需要经常从 /src 中取文件&#xff0c;在每个层级的文件中引用时的相对路径 ../../src ../src 都不…

Centos7中docker安装教程-详细版

卸载旧版&#xff08;如果有&#xff09; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine \docker-selinux 若没有&#xff1a; 检查网络&#xff1a; ping 8.8.8.8 …

电脑软件:推荐一款免费且实用的电脑开关机小工具

目录 一、软件简介 二、软件功能 三、软件特点 四、使用说明 五、软件下载 今天给大家推荐一款免费且实用的电脑开关机小工具KShutdown&#xff0c;有需要的朋友可以下载试一下&#xff01; 一、软件简介 KShutdown是一款精巧且实用的定时自动关机小工具&#xff0c;对于…

SQL Server身份验证模式

SQL Server是一个广泛使用的关系数据库管理系统&#xff0c;通常使用两种身份验证模式&#xff1a;Windows身份验证和SQL Server身份验证。理解这些身份验证方式的概念与更改方式的操作&#xff0c;对于数据库管理员和开发者至关重要。本文将详细介绍身份验证方式的概念以及如何…

Golang | Leetcode Golang题解之第525题连续数组

题目&#xff1a; 题解&#xff1a; func findMaxLength(nums []int) (maxLength int) {mp : map[int]int{0: -1}counter : 0for i, num : range nums {if num 1 {counter} else {counter--}if prevIndex, has : mp[counter]; has {maxLength max(maxLength, i-prevIndex)} …

ML2001-1 机器学习/深度学习 Introduction of Machine / Deep Learning

图片说明来自李宏毅老师视频的学习笔记&#xff0c;如有侵权&#xff0c;请通知下架 影片参考 【李宏毅】3.第一节 - (上) - 机器学习基本概念简介_哔哩哔哩_bilibili 1. 机器学习的概念与任务类型 概念&#xff1a;机器学习近似于寻找函数&#xff0c;用于处理不同类型的任…

打响反对人工智能的第一枪

序言&#xff1a;人工智能的讨论不能只有一片叫好的声音&#xff0c;一味的追捧反而可能隐藏巨大的危机。因此&#xff0c;必须有反对的声音&#xff0c;且越强烈越能激发深入思考。本篇文章的作者就以犀利的视角&#xff0c;漂亮地打响了反对人工智能应用的第一枪。 我以前一…

ubuntu运行gazebo导致内存越来越少

1.用vscode看代码会一直有没用的日志缓存&#xff0c;可以删掉&#xff08;文件夹留着&#xff0c;可以把里面的东西删掉&#xff09; 2.运行gazebo的模型会有很多缓存文件&#xff0c;可以删掉 log文件夹非常大

动态规划之两个数组的 dp(上)

文章目录 最长公共子序列不相交的线不同的子序列通配符匹配 最长公共子序列 题目&#xff1a;最长公共子序列 思路 选取s1的[0, i]区间以及s2的[0&#xff0c; j]区间作为研究对象 状态表示&#xff1a;dp[i][j]表示&#xff0c;s1的[0, i]区间以及s2的[0&#xff0c; j]区间内…

中仕公考:25年上海省考时间

打算参加2025年上海省考的考生&#xff0c;中仕公考为大家整理了24年的考试时间点做参考。 报名时间:11月4日-11月10日 缴费时间:11月4日-11月11日 准考证打印时间:12月6日-12月9日 笔试时间:12月10日 9:00-11:30申论 13:30-15:30行政职业能力测验 16:15-17:15专业科目 …

智能指针(内存泄漏问题)

&#x1f33b;个人主页&#xff1a;路飞雪吖~ &#x1f320;专栏&#xff1a;C/C 目录 一、为什么需要智能指针&#xff1f; 二、内存泄露 三、智能指针的使用及原理 ⭐RAII ⭐智能指针的原理 &#x1f320;小贴士&#xff1a; ⭐std::auto_ptr ​编辑 ✨auto_ptr模拟实…

CSS例子: 横向排列的格子

效果 HTML <view class"content"><view class"item" v-for"item of 5">{{item}}</view></view> CSS .content {height: 100vh;display: flex;flex-direction: row; flex-wrap: wrap;align-content: flex-start;backgro…

面试题分享1

2024.11.1 1、过滤器和拦截器的区别 过滤器是基于spring的 拦截器是基于Java Web的 2、session 和 cookie 的区别、关系 cookie session 存储位置 保存在浏览器 &#xff08;客户端&#xff09; 保存在服务器 存储数据大小 限制大小&#xff0c;存储数据约为4KB 不限…

Python酷库之旅-第三方库Pandas(186)

目录 一、用法精讲 861、pandas.Index.names属性 861-1、语法 861-2、参数 861-3、功能 861-4、返回值 861-5、说明 861-6、用法 861-6-1、数据准备 861-6-2、代码示例 861-6-3、结果输出 862、pandas.Index.nbytes属性 862-1、语法 862-2、参数 862-3、功能 8…

Ansible 部署应用

Ansible Ansible 是基于 Python 开发&#xff0c;集合了众多优秀运维工具的优点&#xff0c;实现了批量运行命令、部署程序、配置系统等功能的自动化运维管理工具。默认通过 SSH 协议进行远程命令执行或下发配置&#xff0c;无需部署任何客户端代理软件&#xff0c;从而使得自动…

Python的全局锁GIL解析

Python的全局锁&#xff08;GIL&#xff09;是 CPython 解释器实现中的一个机制&#xff0c;用来确保任何时候只有一个线程执行 Python 字节码。这一机制存在于 CPython 中&#xff0c;主要是为了确保线程操作中的数据一致性&#xff0c;但也因此限制了多线程的并行执行效率。尤…

基于vue框架的的考研信息共享平台v0eyp(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;国家政策,用户,院校政策,院校信息,考研资料,资料分类,考研论坛 开题报告内容 基于Vue框架的考研信息共享平台开题报告 一、研究背景与意义 随着考研人数的逐年增长&#xff0c;考研学生对高效、便捷、个性化的信息获取需求愈发强烈。…

抽丝剥茧 分布式服务框架设计 理论设计篇

1、概述 前面几篇文章给大家详细的介绍了Zookeeper的基础概念以及应用的领域&#xff0c;今天我们讨论的话题是如何自研一套分布式服务框架。早些年有很多基于Dubbo和Zookeeper的分布式系统&#xff0c;这篇文章我们就来聊下如何设计一个分布式服务框架。 2、系统间交互 2.1、…

C++STL——list

C教学总目录 list 1、list简介2、构造函数3、迭代器4、访问和容量函数5、修改类函数6、操作类函数 1、list简介 list是带头双向循环链表&#xff0c;也是模板类&#xff0c;使用时要指明类型&#xff0c;包含于头文件<list> 由于list是双向循环链表&#xff0c;在任意位置…

YoloV8改进策略:Block改进|RFE模块,提高小物体的识别精度|即插即用|代码+修改过程

摘要 论文介绍 本文介绍了一种基于YOLOv5的人脸检测方法,命名为YOLO-FaceV2。该方法旨在解决人脸检测中的尺度变化、简单与困难样本不平衡以及人脸遮挡等问题。通过引入一系列创新模块和损失函数,YOLO-FaceV2在WiderFace数据集上取得了优异的表现,特别是在小物体、遮挡和困…