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

news/2024/11/2 11:18:55/

前言

有时候列表存在许多图片,那么一次性加载会阻塞 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.ppmy.cn/news/1543849.html

相关文章

深度学习中的核心概念详解

目录 前言1. 深度神经网络与残差网络1.1 深度神经网络的挑战1.2 残差网络的提出与实现1.3 残差网络的作用 2. 词向量&#xff1a;语义理解的基础2.1 词向量的基本概念2.2 词向量的实现方法与作用 3. 对象嵌入&#xff1a;从词向量到对象表示3.1 对象嵌入的概念3.2 对象嵌入的应…

【SSM详细教程】-15-Spring Restful风格【无敌详细】

精品专题&#xff1a; 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…

聊一聊Elasticsearch的基本原理与形成机制

1、搜索引擎的基本原理 通常搜索引擎包括&#xff1a;数据采集、文本分析、索引存储、搜索等模块&#xff0c;它们之间的协作流程如下图&#xff1a; 数据采集模块负责采集需要搜索的数据源。 文本分析模块是将结构化数据中的长文本切分成有实际意义的词&#xff0c;这样用户…

EMR Serverless Spark:一站式全托管湖仓分析利器

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 李钰&#xff08;绝顶&#xff09; | 阿里云智能集团资深技术专家&#xff0c;阿里云 EMR 团队负责人 活动&#xff1a; 2024 云栖大会 AI - 开源大数据专场 数据平台技术演变 …

【React】配置图标和题目

图标和题目这些基本配置都是在 public/index.html&#xff0c;直接修改 link 中的 favicon.ico 就是修改图标&#xff1b;title 标签就是题目修改。 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><link rel&…

stm32——GPIO开发

目录 1、什么是GPIO 2、GPIO的作用 3、GPIO的基本结构 4、GPIO引脚的基本结构 5、GPIO端口模式的配置 1. 输入浮空&#xff08;Input Floating&#xff09; 2. 输入上拉&#xff08;Input Pull-Up&#xff09; 3. 输入下拉&#xff08;Input Pull-Down&#xff09; 4. …

什么是Web3D交互展示?有什么优势?

在智能互联网的新纪元&#xff0c;传统的图片、文字及视频展示方式&#xff0c;因缺乏互动性&#xff0c;正逐渐失去其宣传的吸引力与优势。而Web3D交互展示技术的崛起&#xff0c;为众多品牌与企业开辟了新的展示路径&#xff0c;使得线上产品展示变得生动立体、交互性强&…

Apache paimon表管理

表管理 2.9.4.1 管理快照 1)快照过期 Paimon Writer每次提交都会生成一个或两个快照。每个快照可能会添加一些新的数据文件或将一些旧的数据文件标记为已删除。然而,标记的数据文件并没有真正被删除,因为Paimon还支持时间旅行到更早的快照。它们仅在快照过期时被删除。 …