当前位置: 首页 > ops >正文

懒加载详细讲解

文章目录

      • 🖼️ 懒加载的工作原理
      • 🛠️ 懒加载的实现方式
        • 1. 图片懒加载
        • 2. 组件懒加载(代码分割)
        • 3. 其他资源懒加载
      • ⚠️ 懒加载的注意事项与优化策略
      • 💎 总结

懒加载(Lazy Loading)是一种重要的性能优化技术,其核心思想是 延迟加载非关键资源,直到它们真正需要被使用时才进行加载。这能有效减少初始加载时间,节省带宽,并提升用户体验。

下面是一个表格,汇总了懒加载的主要应用场景、实现方式和优缺点:

方面说明
核心思想延迟加载非关键资源,按需加载。
主要应用场景图片、视频、脚本、组件(代码分割)、长列表/分页数据。
关键实现技术Intersection Observer API(推荐)、滚动事件监听、loading="lazy"属性(原生图片懒加载)。
主要优点加速页面加载、减轻服务器压力、节省带宽、提升用户体验。
潜在缺点与注意事项可能影响SEO、实现复杂度、需平衡性能与用户体验。

🖼️ 懒加载的工作原理

懒加载的技术原理主要基于视口(Viewport)检测。浏览器中用户可见的区域称为视口。懒加载机制通过监测目标元素是否进入或接近视口,来决定是否加载该资源。

  1. 初始状态:需要懒加载的资源(如图片)并不会直接设置 src 属性(对于图片),而是将其真正的资源路径存储在一个自定义属性(如 data-src)中,而 src 属性可能是一个占位图或为空。
  2. 监听与判断:通过 JavaScript 监听滚动事件或使用现代的 Intersection Observer API,来判断元素是否进入了用户的视口。
  3. 触发加载:一旦元素进入或接近视口,便将自定义属性(如 data-src)中存储的真实资源地址赋给 src 属性(对于图片)或执行相应的加载操作(对于脚本、组件等),从而触发浏览器下载并渲染该资源。

🛠️ 懒加载的实现方式

1. 图片懒加载

这是懒加载最常见的应用场景。

  • 使用 Intersection Observer API (推荐)
    Intersection Observer 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"><!-- 更多图片 --></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>
    

    通过 rootMargin (如 "200px 0px") 可以设置提前加载的距离。threshold 用于设置触发加载的可见比例。

  • 使用滚动事件监听(传统方法)
    Intersection Observer API 出现之前或需要兼容旧浏览器时,可通过监听 scroll 事件,结合 getBoundingClientRect() 等方法计算元素位置来实现。

    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);
    

    为了性能考虑,通常需要对滚动事件处理函数进行防抖(Debounce)或节流(Throttle)

  • 原生 loading="lazy" 属性
    现代浏览器为 <img><iframe> 标签提供了原生的懒加载支持。只需简单地为标签添加 loading="lazy" 属性即可。

    <img src="image.jpg" loading="lazy" alt="Lazy Loaded Image">
    

    此方式最简单,但可定制性和浏览器兼容性可能不如 Intersection Observer API

2. 组件懒加载(代码分割)

在单页应用(SPA)中,可以使用框架提供的功能实现组件的懒加载,这通常与打包工具的代码分割功能结合使用。

  • React 中的 React.lazySuspense

    import React, { Suspense } from 'react';
    const MyComponent = React.lazy(() => import('./MyComponent')); // 动态导入
    function App() {return (<div><Suspense fallback={<div>Loading...</div>}><MyComponent /></Suspense></div>);
    }
    
  • Vue 中的 defineAsyncComponent

    import { defineAsyncComponent } from 'vue';
    export default {components: {MyComponent: defineAsyncComponent(() => import('./MyComponent.vue'))}
    }
    
3. 其他资源懒加载
  • 脚本懒加载:对于非关键第三方脚本(如分析、广告脚本),可以通过 JavaScript 动态创建 <script> 标签并添加到 DOM 中。

    const script = document.createElement('script');
    script.src = 'https://example.com/script.js';
    script.async = true;
    document.body.appendChild(script);
    
  • 数据懒加载:在长列表或分页应用中,只有当用户滚动到列表底部或点击“加载更多”时,才通过 AJAX 或 Fetch API 请求下一页数据。更高级的实现如虚拟滚动,只渲染可视区域内的项。

⚠️ 懒加载的注意事项与优化策略

  1. SEO 影响:搜索引擎爬虫可能无法执行 JavaScript 或滚动页面,导致懒加载的内容未被抓取。解决方案包括:

    • 使用服务器端渲染(SSR)。
    • 确保关键内容最初已在 HTML 中。
    • 使用 <noscript> 标签或遵循 Google 等搜索引擎关于懒加载内容的指南。
  2. 占位符与布局稳定性:在资源加载前,应使用占位符(如低分辨率图像、纯色背景或相同尺寸的空白块)来避免页面布局突然跳动,提升 Core Web Vitals 中的 Cumulative Layout Shift (CLS) 指标。

  3. 预加载与触发时机:通过 Intersection Observer APIrootMargin 参数,可以提前加载即将进入视口的资源,避免用户看到明显的加载过程。

  4. 错误处理:网络请求可能会失败,应为资源加载添加错误处理。例如,图片加载失败时显示一个默认错误图片。

    img.onerror = function() {this.src = "default.jpg";
    };
    
  5. 性能监控与平衡:懒加载虽好,但不宜过度。需要监控页面性能,确保懒加载不会因频繁加载大量小资源而反而导致性能下降。

💎 总结

懒加载通过按需加载非关键资源,是优化网页性能、提升用户体验的有效手段。Intersection Observer API 是实现懒加载的现代推荐方式。虽然懒加载可能带来一些SEO和实现复杂性的挑战,但通过合理的技术选型和处理,利远大于弊。

http://www.xdnf.cn/news/19498.html

相关文章:

  • 使用修改过的arj源码编译和测试
  • C++ 学习与 CLion 使用:(五)数据类型,包括整型、实型、字符型、转义字符、字符串、布尔型
  • 从DevOps到BizDevOps:哪些DevOps工具能够成为业务创新加速引擎?
  • 响应式编程框架Reactor【8】
  • Notepad++近期版本避雷
  • 中心扩展算法
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘tox’问题
  • 利用 DrissionPage 精准获取淘宝商品描述:Python 爬虫实战指南
  • C/C++、Python和Java语言的比较
  • 【职业】算法与数据结构专题
  • 15693协议ICODE SLI 系列标签应用场景说明及读、写、密钥认证操作Qt c++源码,支持统信、麒麟等国产Linux系统
  • 浪潮科技Java开发面试题及参考答案(120道题-上)
  • 利用本地电脑上的MobaXterm连接虚拟机上的Ubuntu
  • 基于SpringBoot音乐翻唱平台
  • Linux Shell 脚本中括号类型及用途
  • three.js+WebGL踩坑经验合集(10.2):镜像问题又一坑——THREE.InstancedMesh的正反面向光问题
  • UART-TCP双向桥接服务
  • 【51单片机三路抢答器定时器1工作1外部中断1】2022-11-24
  • 参数检验vs非参数检验
  • docker 网络配置
  • 【高级】系统架构师 | 2025年上半年综合真题
  • 硬件开发_基于Zigee组网的果园养殖监控系统
  • 56_基于深度学习的X光安检危险物品检测系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • aws上创建jenkins
  • 力扣 23 912题(堆)
  • JAVA 面试宝典02
  • 工业飞拍技术:高速生产线的 “动态抓拍神器”,到底牛在哪?
  • 20250829的学习笔记
  • 基于GCN图神经网络的光伏功率预测Matlab代码
  • Spark实现推荐系统中的相似度算法