如何深入理解 JavaScript 中的懒加载

news2025/1/11 18:35:12

0316335cd7d0436f2a52bdb6bccead77.jpeg

懒加载是一种延迟加载非必要内容的方法,直到用户需要查看它为止。与其他加载方法不同,其他加载方法在访问页面时同时加载所有网站资源,而懒加载采取更加谨慎的方式。它延迟显示某些元素,如图片、视频和其他多媒体,直到用户主动与网页进行交互。本文将向您展示如何使用懒加载,以便您的用户在访问您的网站时获得更好的体验。

介绍

网络用户对网站加载时间和性能有很高的期望。加载缓慢的网站可能会增加跳出率并让用户感到不满意。为了应对这一挑战,开发人员不断寻求不同的技术来提高速度和整体用户体验,其中一种方法就是“懒加载”。为了实现懒加载,开发人员使用JavaScript。通过使用JavaScript,Web开发人员可以控制特定元素从服务器获取和渲染到用户屏幕的时间和方式。本文将探讨懒加载的好处、实施方法、对Web性能的影响、挑战和最佳实践。

懒加载的好处

  • 减少带宽使用:加载不必要的资源会消耗大量带宽,影响用户和网站所有者。延迟加载可以通过仅加载所需资源来节省带宽。对于可能不会向下滚动查看整个页面的访问者来说,这将变得有益,因为它可以帮助防止他们超出每月限额。

  • 提高页面速度得分和增强SEO性能:搜索引擎将页面速度视为排名因素之一。通过改善加载时间,延迟加载对Google的PageSpeed等各种工具测量的页面速度得分产生积极影响。更高的页面速度得分改善了SEO,并有助于提高用户留存率和转化率。

  • 减少服务器负载:通过按需获取资源,它有助于更高效地分配服务器负载。它减轻了服务器压力,使其能够处理更多的用户请求。

  • 改进的交互时间(TTI):交互时间测量网页完全交互所需的时间,允许用户与按钮、链接和其他元素进行交互。通过优先加载重要内容,惰性加载有助于减少TTI,为用户提供更愉悦的浏览体验。

  • 优化移动浏览和改善用户体验:移动设备通常具有有限的处理能力和网络功能。通过采用延迟加载,网站适应这些限制,提供更流畅的体验并减少数据消耗,使其更适合移动设备。用户可以快速与可见内容交互,而无需等待屏幕外资源加载。

JavaScript中实现延迟加载的技术

在JavaScript中,可以通过不同的方法实现延迟加载。然而,两种广泛使用的技术是使用Intersection Observer API来延迟加载图像,以及在滚动事件中实现内容的延迟加载。让我们通过示例来探讨这两种技术,以了解它们的工作原理:

1、使用Intersection Observer API进行图片的懒加载

Intersection Observer API是一个JavaScript API,允许开发人员观察元素与特定祖先或视口的交叉变化。它跟踪目标元素的可见性,并在元素进入或离开视图时通知开发人员。它非常适用于延迟加载图像,因为它在图像进入或离开视口时通知我们,从而允许我们根据需要加载图像。它在一个单独的线程上运行,不会阻塞主JavaScript线程。该API不仅限于图像,还可以用于延迟加载任何内容,例如视频、iframe甚至是生成的页面部分。

多个Intersection Observers可以同时观察同一页上的不同元素。例如,假设您有一个页面上有多个图像,并且希望在用户向下滚动页面时延迟加载这些图像。下面是如何使用Intersection Observer API和原生JavaScript实现延迟加载的方法。要开始,请确保您有一个基本的HTML结构,其中包含带有 img 标签的 data-src 属性,指定图像的实际源URL。我们将使用 data-src 来存储图片的URL,而不是使用传统的 src 属性来实现图片的懒加载。

<!DOCTYPE html>
<html>
<head>
 <title>Lazy Loading Images</title>
</head>
<body>
 <h1>Lazy Loading Images Example</h1>
 <img class="lazy" data-src="image1.jpg" alt="Image 1">
 <img class="lazy" data-src="image2.jpg" alt="Image 2">
 <!-- Add more images with the "lazy" class and "data-src" attribute -->
</body>
</html>

在我们的JavaScript代码中,我们将创建一个Intersection Observer的实例,并指定一个回调函数,每当观察的元素进入或离开视口时,该函数将被触发。

// Get all elements with the "lazy" class
const lazyImages = document.querySelectorAll(".lazy");
// Create a new Intersection Observer
const observer = new IntersectionObserver((entries, observer) => {
 entries.forEach((entry) => {
  if (entry.isIntersecting) {
   // Load the image when it comes into the viewport
   entry.target.src = entry.target.dataset.src;
   observer.unobserve(entry.target); // Unobserve the image after it's loaded
  }
 });
});
// Observe each lazy image
lazyImages.forEach((image) => {
 observer.observe(image);
});

在上面的代码中,首先使用 document.querySelectorAll(".lazy") 选择所有具有“lazy”类的元素。然后,我们创建一个新的Intersection Observer实例,传入一个回调函数,每当观察的元素(在这种情况下是懒加载的图片)进入或退出视口时触发。当观察到一张图片并进入视口时(即 entry.isIntersecting 为真),我们将其 src 属性设置为 data-src 的值,该值保存了实际的图片URL。这个操作触发了图片的懒加载。然后,我们调用 observer.unobserve(entry.target) 来停止观察图片一旦加载完成以优化性能。

2. 滚动事件上的懒加载内容:

基于滚动事件的方法可以实现高度定制的懒加载实现。您可以完全控制内容何时以及如何加载,使其适用于需要在元素可见时执行特定任务或转换的场景。滚动事件是JavaScript的一个特性,被所有现代浏览器支持。这意味着您不必担心兼容性问题。

对于单页应用程序,其中内容随着用户浏览网站而加载,使用滚动事件可能更直观。与Intersection Observer API最适合图像和特定元素不同,基于滚动事件的懒加载提供了更多的灵活性。您可以将其应用于任何内容或复杂组件,这些内容可能不适合“在视图中”的概念。让我们看一个例子。在这里,您将再次拥有一个基本的HTML结构,其中包含要惰性加载的元素。但是,这次我们不需要像 data-src 这样的特殊属性。

<!DOCTYPE html>
<html>
<head>
 <title>Lazy Loading Content on Scroll</title>
</head>
<body>
 <h1>Lazy Loading Content Example</h1>
 <div class="lazy-content">
  <p>Some content to be lazily loaded...</p>
 </div>
 <div class="lazy-content">
  <p>More content to be lazily loaded...</p>
 </div>
 <!-- Add more elements with the "lazy-content" class -->
</body>
</html>

在我们的JavaScript代码中,你将会有一个函数 isElementInViewport(element) ,它会检查一个元素是否在视口中,然后定义一个 lazyLoadContent() 函数,该函数使用 document.querySelectorAll(".lazy-content") 遍历所有具有“lazy-content”类的元素。

// Function to check if an element is in the viewport
function isElementInViewport(element) {
 const rect = element.getBoundingClientRect();
 return (
  rect.top >= 0 &&
  rect.left >= 0 &&
  rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
  rect.right <= (window.innerWidth || document.documentElement.clientWidth)
 );
}
// Function to lazily load content
function lazyLoadContent() {
 const lazyContentElements = document.querySelectorAll(".lazy-content");
 lazyContentElements.forEach((element) => {
  if (isElementInViewport(element)) {
   // Add your logic to load the content for the element here
   element.classList.add("loaded");
  }
 });
}
// Attach the lazyLoadContent function to the scroll event
window.addEventListener("scroll", lazyLoadContent);
// Call the function initially to load the visible content on page load
lazyLoadContent();

对于每个元素,它使用 isElementInViewport(element) 检查它是否在视口中,如果为真,则加载该元素的内容。在这个例子中,我们只是给元素添加一个类名“loaded”,但你可以根据你的使用情况自定义这部分。然后,我们使用 window.addEventListener("scroll", lazyLoadContent) 将 lazyLoadContent() 函数附加到滚动事件上。这确保了每当用户滚动页面时都会调用该函数。此外,我们在页面加载时调用 lazyLoadContent() 来加载可见内容。

何时使用懒加载

对于网页开发人员来说,知道何时实施延迟加载是很重要的。明智地使用它以最大化其效果并避免潜在的缺点是至关重要的。延迟加载是那些严重依赖图片的网站必备的优化功能,比如在线作品集、电子商务平台和摄影网站。这些网站通常展示大量高分辨率的图片,这些图片会显著影响初始页面加载时间。

通过延迟加载图片,只有用户视口内或可见区域的图片会最先加载。利用无限滚动或分页来展示大量内容的网页可以从延迟加载中受益。带有交互元素和小部件(如滑块、轮播图和手风琴)的页面也可以利用延迟加载。跨多个页面的长文章或博客文章也可以从延迟加载中受益。与预加载所有页面不同,延迟加载可以在用户滚动到当前页面末尾时获取和加载后续页面。具有资源密集型功能的网站,例如交互式地图、数据可视化和复杂动画,可以使用延迟加载来优化性能。

懒加载的挑战

虽然JavaScript中的懒加载有助于提高网页性能,但也面临一些挑战。与懒加载相关的一些挑战包括:

  • JavaScript 依赖:延迟加载依赖 JavaScript 来获取和加载所需资源。然而,并非所有用户的浏览器都启用了 JavaScript。在这种情况下,延迟加载的内容可能无法加载,从而给部分用户带来糟糕的用户体验。

  • 复杂的实现:实现延迟加载可能变得复杂,特别是在具有复杂结构和各种类型资源的网站上。管理多个延迟加载元素,确保它们在正确的时间加载,并处理交互可能具有挑战性。

  • 管理图像尺寸:在响应式设计中,懒加载图像在处理不同屏幕尺寸和分辨率时可能会变得具有挑战性。

最佳实践

开发人员应遵循最佳实践,以充分发挥JavaScript中的延迟加载的潜力。在将延迟加载应用于网站之前,要确定应立即加载的重要内容,以创建良好的用户体验。让我们来看一些实施延迟加载的最佳实践:

  • 优化图像和媒体文件:为了优化图像的懒加载,使用适当的图像格式并在不损失质量的情况下进行压缩。使用 srcset 和 sizes 属性实现响应式图像,根据用户的视口提供不同的图像尺寸,节省带宽。

  • 使用占位元素:为了防止内容移动和布局不稳定,使用占位元素来保留懒加载内容的空间。可以使用占位图像或简单的占位符,比如具有定义尺寸和背景颜色的div元素,以保持布局直到实际内容加载完成。

  • 实现Intersection Observer API:Intersection Observer API是一种简化懒加载实现的JavaScript功能。它允许开发人员高效地跟踪元素何时进入视口,从而触发懒加载内容的加载。

  • 为JavaScript禁用的用户提供备选方案:并非所有用户都在其浏览器中启用了JavaScript。为了满足这些用户的需求,为延迟加载的内容提供备选解决方案。例如,使用 <noscript> 标签来包含延迟加载图像和媒体的静态版本。这样可以确保禁用JavaScript的用户仍然可以访问重要内容,并保持良好的用户体验。

  • 处理错误:延迟加载有时可能会导致错误,例如损坏的图像URL或资源加载失败。实现错误处理以优雅地处理这些情况。用适当的占位符替换损坏或缺失的图像,并将错误记录到控制台以进行调试。错误处理有助于为用户提供无缝体验,并帮助开发人员识别和解决问题。

  • 保持懒加载轻量化:避免过度加载网页,限制仅对显著影响页面加载时间的元素进行懒加载。

  • 在各种设备、浏览器和网络速度上彻底测试:在将懒加载应用到实际网站之前,请在各种设备、浏览器和网络速度上彻底测试其实施。在台式机、笔记本电脑、平板电脑和智能手机上进行测试,以确保行为和响应性的一致性。

  • 在将图像插入DOM之前,异步解码图像,这样可以防止浏览器在图像加载时冻结。

结束

懒加载是一种使网站更快、更易于使用的方法。它通过等待在需要时再加载不重要的内容来实现。这意味着您可以更快地看到页面并使用更少的数据。在JavaScript中实现懒加载时,浏览器的兼容性是另一个需要考虑的因素。虽然许多现代浏览器支持懒加载所需的功能和API,但旧版本的浏览器可能缺乏支持或功能有限。因此,开发人员必须注意他们想要支持的浏览器,并相应选择适当的技术。本文介绍了懒加载的好处、技术、挑战和最佳实践,为现代网页开发中懒加载的潜力提供了启示。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

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

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

相关文章

【python利用shp文件进行绘图白化】

python白化 白化的作用python实现 白化的作用 参考博文【matlab利用shp文件制作mask白化文件】 python实现 python借助shp文件对绘图进行白化&#xff0c;不需要进行mask文件的制作&#xff0c;可以高效地进行区域绘制 import numpy as np import cartopy.crs as ccrs impo…

JUC--线程池

目录 一、线程池的介绍 二、线程池的创建 三、特殊线程池 3.1.CompletionService异步处理 3.2.ThreadPoolExecutor 3.3 ForkJoinPool 虽然多线程的技术大大帮助了程序运行的效率&#xff0c;但是在太多的线程的创建与销毁下&#xff0c;系统的开销也将会是非常庞大的。所以…

ChatGPT赋能低代码开发:打造智能应用的双重引擎

摘要&#xff1a;本文摘自葡萄城低代码产品活字格的资深用户&#xff08;格友超哥&#xff09;所撰写的文章&#xff1a;《惊叹表现&#xff01;活字格ChatGPT&#xff1a;低代码开发智能应用的巨大潜力》。 ChatGPT的functions函数使用方 自从OPENAI发布了最新的GPT引擎gpt-3…

由银行保险业科技外包供应商安全风险事件,看金融行业供应链安全

近日&#xff0c;金融监管总局下发《关于加强第三方合作中网络和数据安全管理的通知》&#xff0c;通知中提到&#xff1a;近期发生多起银行保险外包供应商安全⻛险事件&#xff0c;对银行保险机构的网络系统安全、业务连续性造成一定影响&#xff0c;暴露出银行保险机构在外包…

春秋云镜:CVE-2018-19422(Subrion CMS 4.2.1 存在文件上传漏洞)

一、题目 靶标介绍&#xff1a; Subrion CMS 4.2.1 存在文件上传漏洞 进入题目&#xff1a; admin/admin 点击设置&#xff1a; 后台管理主页&#xff1a; 上传页面&#xff1a; 上传目录&#xff1a; /panel/uploads/ 查看上传位置&#xff1a; system.pht<?php sys…

Lua代码实现鼠标宏

注意&#xff1a;本文仅是技术交流&#xff0c;滥用技术者将自行承担后果 目录 一、什么是鼠标宏 二、射击游戏鼠标宏的制作原理 三、FPX鼠标宏带来的危害 一、什么是鼠标宏 鼠标宏是一种使用特定软件或设备编写和执行的自动化脚本&#xff0c;用于模拟和复制鼠标操作。它可…

PowerDesigner书签显示comment字段注释内容

1.今日书签 PowerDesigner 16.5 对表字段设置显示 comment 注释&#xff0c;解决视图模型看不到表字段 comment 中文注释的问题。 2.拨云见日 2.1.操作环境 操作系统&#xff1a;Win10 PowerDesigner 版本&#xff1a;16.5 2.2.操作步骤 无论 PowerDesigner 15 还是 Powe…

Vue 中 diff 算法原理

一、Diff 概念 Vue 基于虚拟 DOM 做更新。diff 算法的核心就是比较两个虚拟节点的差异。 Vue 的 diff 算法是平级比较&#xff08;如图&#xff0c;父级和父级比较&#xff0c;儿子和儿子比较&#xff0c;孙子和孙子比较&#xff09;&#xff0c;不考虑跨级比较的情况&#x…

企业专网?公网?工业4G路由器如何正确选择SIM卡?

选择合适的SIM卡对工业4G路由器稳定通信至关重要。但是面对企业专网和公网两种选择,用户该如何抉择呢?本文将全面解析专网卡与公网卡的区别、适用场景及选择要点,并推荐星创易联SR700等产品的匹配方案,助你正确选择最合理的工业SIM卡。 首先,从网络质量上,企业专网较公网更稳定…

韩语翻译器拍照翻译方法,几个步骤轻松翻译

韩语是一种非常有趣的语言&#xff0c;但对于大多数人来说&#xff0c;是非常难以掌握的。 如果你正在韩国旅行或生活&#xff0c;你可能会遇到许多韩语文字和标志&#xff0c;这时候拍照翻译就派上用场了。 许多智能手机都有支持翻译应用&#xff0c;但是如何在手机上拍照并翻…

Java版B/S架构 智慧工地源码,PC、移动、数据可视化智慧大屏端源码

智慧工地是什么&#xff1f;智慧工地主要围绕绿色施工、安全管控、劳务管理、智能管理、集成总控等方面&#xff0c;帮助工地解决运营、管理方面各个难点痛点。在互联网的加持下促进项目现场管理的创新与发展&#xff0c;实现工程管理人员与工程施工现场的整合&#xff0c;构建…

一网打尽java注解-克隆-面向对象设计原则-设计模式

文章目录 注解内置注解元注解 对象克隆为什么要克隆&#xff1f;如何克隆浅克隆深克隆 Java设计模式什么是设计模式&#xff1f;为什么要学习设计模式&#xff1f; 建模语言类接口类之间的关系依赖关系关联关系聚合关系组合关系继承关系实现关系 面向对象设计原则单一职责开闭原…

速通蓝桥杯嵌入式省一教程:(九)AT24C02芯片(E2PROM存储器)读写操作与I2C协议

AT24C02芯片&#xff08;又叫E2PROM存储器、EEPROM存储器&#xff09;&#xff0c;是一种通过I2C(IIC)协议通信的掉电保存存储器芯片&#xff0c;其内部含有256个8位字节。在介绍这款芯片之前&#xff0c;我们先来粗略了解一下I2C协议。 I2C总线是一种双向二线制的同步串行总线…

BLFS学习系列 第26章. 显示管理器 —— 总述

显示管理器&#xff08;Display Manager&#xff09;是用于启动图形显示&#xff08;当前为X服务器&#xff09;并为窗口管理器或桌面环境提供登录功能的图形程序。 有许多显示管理器可用。一些较为知名的包括&#xff1a;GDM、KDM&#xff08;已弃用&#xff09;、LightDM、L…

ssm助学贷款系统源码和论文

ssm助学贷款系统源码和论文050 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&am…

Java注解语法

Java注解语法 1. 前置基础 ​ 学习java反射语法 JAVA通过反射使用公共构造方法和私有构造方法来创建对象 2. Java注解是什么&#xff1f; ​ Java注解是代码中的特殊标记&#xff0c;比如Override、Test等&#xff0c;作用是&#xff1a;让其他程序根据注解 信息决定怎么执…

【ECCV2022】Swin-Unet: Unet-like Pure Transformer for Medical Image Segmentation

Swin-Unet: Unet-like Pure Transformer for Medical Image Segmentation 论文&#xff1a;https://arxiv.org/abs/2105.05537 代码&#xff1a;https://github.com/HuCaoFighting/Swin-Unet 解读&#xff1a;Swin-UNet&#xff1a;基于纯 Transformer 结构的语义分割网络 -…

【FAQ】视频云存储/安防监控EasyCVR视频汇聚平台如何通过角色权限自行分配功能模块?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

SpringMVC 写个 HelloWorld

文章目录 一、SpringMVC简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式&#xff1a;warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求控制器5、创建springMVC…