懒加载(Lazy Loading):原理、实现与优化策略

news2025/3/13 20:45:26

懒加载(Lazy Loading) 是一种优化网页性能的技术,主要用于延迟加载非关键资源(如图片、视频、脚本等),直到它们真正需要被使用时才加载。懒加载可以显著减少页面初始加载时间,降低带宽消耗,并提升用户体验。


1. 懒加载的核心思想

懒加载的核心思想是 按需加载。具体来说:

  • 初始加载:只加载当前视口(Viewport)内的资源,或者只加载用户可见的内容。
  • 延迟加载:当用户滚动页面或资源进入视口时,再动态加载这些资源。

2. 懒加载的应用场景

  1. 图片懒加载:延迟加载页面中的图片,直到图片进入视口。
  2. 视频懒加载:延迟加载视频资源,直到用户点击播放按钮。
  3. 脚本懒加载:延迟加载非关键脚本,直到页面主要内容加载完成。
  4. 分页加载:在长列表或分页内容中,只加载当前可见的部分,滚动时再加载更多内容。

3. 图片懒加载的实现

图片懒加载是最常见的懒加载场景。以下是两种实现方式:

方法 1:使用 IntersectionObserver API(推荐)

IntersectionObserver 是浏览器提供的一个 API,用于监听目标元素是否进入视口。

代码实现
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lazy Loading Images</title>
    <style>
        img {
            width: 100%;
            height: 300px;
            background: #eee;
            display: block;
            margin-bottom: 20px;
        }
    </style>
</head>
<body>
    <div>
        <img data-src="https://picsum.photos/800/600?random=1" alt="Image 1">
        <img data-src="https://picsum.photos/800/600?random=2" alt="Image 2">
        <img data-src="https://picsum.photos/800/600?random=3" alt="Image 3">
        <img data-src="https://picsum.photos/800/600?random=4" alt="Image 4">
        <img data-src="https://picsum.photos/800/600?random=5" alt="Image 5">
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const images = document.querySelectorAll("img[data-src]");

            const observer = new IntersectionObserver((entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const img = entry.target;
                        img.src = img.getAttribute("data-src");
                        img.removeAttribute("data-src");
                        observer.unobserve(img); // 停止观察已加载的图片
                    }
                });
            }, {
                rootMargin: "0px",
                threshold: 0.1 // 当图片进入视口 10% 时触发加载
            });

            images.forEach(img => {
                observer.observe(img); // 开始观察每个图片
            });
        });
    </script>
</body>
</html>
代码解析
  1. data-src 属性:将图片的真实 URL 存储在 data-src 属性中,而不是直接放在 src 属性里。
  2. IntersectionObserver
    • 监听每个图片是否进入视口。
    • 当图片进入视口时,将 data-src 的值赋给 src 属性,触发图片加载。
    • 加载完成后,停止观察该图片。
  3. 性能优化:通过 rootMarginthreshold 参数,可以控制图片进入视口的触发条件。

方法 2:使用滚动事件监听(传统方法)

在没有 IntersectionObserver 的情况下,可以通过监听滚动事件来实现懒加载。

代码实现
function lazyLoadImages() {
    const images = document.querySelectorAll("img[data-src]");
    images.forEach(img => {
        const rect = img.getBoundingClientRect();
        if (rect.top < window.innerHeight && rect.bottom >= 0) {
            img.src = img.getAttribute("data-src");
            img.removeAttribute("data-src");
        }
    });
}

window.addEventListener("load", lazyLoadImages);
window.addEventListener("scroll", lazyLoadImages);
window.addEventListener("resize", lazyLoadImages);
代码解析
  1. getBoundingClientRect():获取图片相对于视口的位置。
  2. 判断条件:如果图片的顶部进入视口(rect.top < window.innerHeight),则加载图片。
  3. 事件监听:在页面加载、滚动和窗口大小变化时触发懒加载。

4. 懒加载的优化

1. 占位符(Placeholder)

在图片加载之前,可以使用一个占位符(如纯色背景或低分辨率图片)来避免页面布局抖动。

<img data-src="image.jpg" src="placeholder.jpg" alt="Image">

2. 预加载

对于即将进入视口的图片,可以提前加载,避免用户滚动时出现空白。

const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.getAttribute("data-src");
            img.removeAttribute("data-src");
            observer.unobserve(img);
        }
    });
}, {
    rootMargin: "200px 0px", // 提前 200px 加载
    threshold: 0.1
});

3. 图片加载失败处理

如果图片加载失败,可以显示一个默认图片。

img.onerror = function() {
    this.src = "default.jpg";
};

5. 懒加载的优缺点

优点

  • 减少初始加载时间:只加载用户可见的内容,提升页面加载速度。
  • 节省带宽:减少不必要的资源加载,降低服务器压力。
  • 提升用户体验:避免页面卡顿,提供更流畅的交互体验。

缺点

  • 实现复杂度:需要额外的代码逻辑来实现懒加载。
  • SEO 影响:如果搜索引擎爬虫无法正确解析懒加载的内容,可能会影响 SEO。

6. 总结

懒加载是一种非常实用的性能优化技术,特别适用于包含大量图片或长列表的页面。通过 IntersectionObserver 或滚动事件监听,可以轻松实现懒加载功能。结合占位符、预加载和错误处理,可以进一步提升用户体验。

在实际项目中,可以根据需求选择合适的懒加载方案,并结合其他优化技术(如防抖、节流)来达到最佳性能。

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

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

相关文章

【MySQL】基本操作 —— DDL

目录 DDLDDL 常用操作对数据库的常用操作查看所有数据库创建数据库切换、显示当前数据库删除数据库修改数据库编码 对表的常用操作创建表数据类型数值类型日期和时间类型字符串类型 查看当前数据库所有表查看指定表的创建语句查看指定表结构删除表 对表结构的常用操作给表添加字…

游戏引擎学习第152天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾昨天的内容 这个节目展示了我们如何从零开始制作一款完整的游戏。我们不使用任何游戏引擎或库&#xff0c;而是从头开始创建一款游戏&#xff0c;整个开发过程都会呈现给大家。你将能够看到每一行代码的编写&#xff0c;了解…

考研数学非数竞赛复习之Stolz定理求解数列极限

在非数类大学生数学竞赛中&#xff0c;Stolz定理作为一种强大的工具&#xff0c;经常被用来解决和式数列极限的问题&#xff0c;也被誉为离散版的’洛必达’方法&#xff0c;它提供了一种简洁而有效的方法&#xff0c;使得原本复杂繁琐的极限计算过程变得直观明了。本文&#x…

故障诊断——neo4j入门

文章目录 neo4jQuickStartDemo neo4j QuickStart 详情可见博客&#xff1a;https://www.cnblogs.com/nhdlb/p/18703804&#xff0c;使用docker拉取最近的一个版本进行创建 docker run -it -d -p 7474:7474 -p 7687:7687 \ -v /disk5/neo4j_docker/data:/data \ -v /disk5/ne…

【JavaWeb】快速入门——HTMLCSS

文章目录 一、 HTML简介1、HTML概念2、HTML文件结构3、可视化网页结构 二、 HTML标签语法1、标题标签2、段落标签3、超链接4、换行5、无序列表6、路径7、图片8、块1 盒子模型2 布局标签 三、 使用HTML表格展示数据1、定义表格2、合并单元格横向合并纵向合并 四、 使用HTML表单收…

若依框架-给sys_user表添加新字段并获取当前登录用户的该字段值

目录 添加字段 修改SysUser类 修改SysUserMapper.xml 修改user.js 前端获取字段值 添加字段 若依框架的sys_user表是没有age字段的&#xff0c;但由于业务需求&#xff0c;我需要新添加一个age字段&#xff1a; 修改SysUser类 添加age字段后&#xff0c;要在SysUser类 …

前端监测窗口尺寸和元素尺寸变化的方法

前端监测窗口尺寸变化和元素尺寸变化的方法 window.resize 简介 window.resize事件是浏览器提供的一种事件&#xff0c;用于监听窗口大小的改变。这意味着当用户调整浏览器窗口大小时&#xff0c;相关的JavaScript代码将被触发执行。这为开发者提供了一种机制&#xff0c;可…

ubuntu 部署deepseek

更新 apt update 升级 apt upgrade 格式化硬盘 mkfs.ext4 /dev/sdb 安装nginx 查看端口 一、安装Ollama Ollama是一个开源的大型语言模型&#xff08;LLM&#xff09;推理服务器&#xff0c;为用户提供了灵活、安全和高性能的语言模型推理解决方案。 ollama/docs/linux.m…

MySQL库和表的操作详解:从创建库到表的管理全面指南

目录 一、MySQL库的操作详解 〇、登录MySQL 一、数据库的创建与字符集设置 1. 创建数据库的语法 2. 创建数据库示例 查看创建出来的文件: bash下查看MySQL创建的文件 二、字符集与校验规则 1. 查看系统默认设置 2. 查看支持的字符集与校验规则 3. 校验规则对查询的影响…

PyTorch 系列教程:使用CNN实现图像分类

图像分类是计算机视觉领域的一项基本任务&#xff0c;也是深度学习技术的一个常见应用。近年来&#xff0c;卷积神经网络&#xff08;cnn&#xff09;和PyTorch库的结合由于其易用性和鲁棒性已经成为执行图像分类的流行选择。 理解卷积神经网络&#xff08;cnn&#xff09; 卷…

Java 大视界 -- Java 大数据中的数据可视化大屏设计与开发实战(127)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

「Unity3D」UGUI将元素固定在,距离屏幕边缘的某个比例,以及保持元素自身比例

在不同分辨率的屏幕下&#xff0c;UI元素按照自身像素大小&#xff0c;会发生位置与比例的变化&#xff0c;本文仅利用锚点&#xff08;Anchors&#xff09;使用&#xff0c;来实现UI元素&#xff0c;固定在某个比例距离的屏幕边缘。 首先&#xff0c;将元素的锚点设置为中心&…

Deep research深度研究:ChatGPT/ Gemini/ Perplexity/ Grok哪家最强?(实测对比分析)

目前推出深度研究和深度检索的AI大模型有四家&#xff1a; OpenAI和Gemini 的deep research&#xff0c;以及Perplexity 和Grok的deep search&#xff0c;都能生成带参考文献引用的主题报告。 致力于“几分钟之内生成一份完整的主题调研报告&#xff0c;解决人力几小时甚至几天…

关于sqlalchemy的ORM的使用

关于sqlalchemy的ORM的使用 二、创建表三、使用数据表、查询记录三、批量插入数据四、关于with...as...:的使用 二、创建表 使用Mapped来映射字段 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker,Mapped,mapped_columnBa…

【leetcode hot 100 148】排序序列

解法一&#xff1a;&#xff08;双重循环&#xff09;第一个循环head&#xff0c;逐步将head的node加入有序列表&#xff1b;第二个循环在有序列表中找到合适的位置&#xff0c;插入node。 /*** Definition for singly-linked list.* public class ListNode {* int val;* …

【Linux】在VMWare中安装Ubuntu操作系统(2025最新_Ubuntu 24.04.2)#VMware安装Ubuntu实战分享#

今天田辛老师为大家带来一篇关于在VMWare虚拟机上安装Ubuntu系统的详细教程。无论是学习、开发还是测试&#xff0c;虚拟机都是一个非常实用的工具&#xff0c;它允许我们在同一台物理机上运行多个操作系统。Ubuntu作为一款开源、免费且用户友好的Linux发行版&#xff0c;深受广…

AutoGen学习笔记系列(十三)Advanced - Logging

这篇文章瞄的是AutoGen官方教学文档 Advanced 章节中的 Logging 篇章&#xff0c;介绍了怎样在使用过程中添加日志信息&#xff0c;其实就是使用了python自带的日志库 logging。 官网链接&#xff1a;https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-g…

scrcpy pc机远程 无线 控制android app 查看调试log

背景&#xff1a; 公司的安卓机&#xff0c;是那种大屏幕的连接usb外设的。不好挪动&#xff0c;占地方&#xff0c;不能直接连接pc机上的android stduio来调试。 所以从网上找了一个python adb.exe控制器&#xff0c;可以局域网内远程控制开发的app,并在android stduio上看…

UE5.5 Niagara发射器更新属性

发射器属性 在 Niagara 里&#xff0c;Emitter 负责控制粒子生成的规则和行为。不同的 Emitter 属性决定了如何发射粒子、粒子如何模拟、计算方式等。 发射器 本地空间&#xff08;Local Space&#xff09; 控制粒子是否跟随发射器&#xff08;Emitter&#xff09;移动。 ✅…

MongoDB备份与还原

备份恢复工具介绍 1&#xff09;mongoexport/mongoimport 2&#xff09;mongodump/mongorestore 备份工具区别 mongoexport/mongoimport 导入/导出的是JSON格式或者CSV格式 mongodump/mongorestore 导入/导出的是BSON格式。二进制方式&#xff0c;速度快 1&#xff09;…