图片懒加载的实现方法

实现图片懒加载的方法 懒加载的概念 懒加载也叫做延迟加载、按需加载,指的是在长网页中延迟加载图片数据,是一种较好的网页性能优化的方式。在比较长的网页或应用中,如果图片很多,所有的图片都被加载出来,而用户只能看到可视窗口的那一部分图片数据,这样就浪费了性能。而使用懒加载的方式就能有效的提高加载性能。 实现原理 我们知道图片的加载是由src引起的,当对src赋值时,浏览器就会请求图片资源。根据这个原理,我们使用HTML5 的data-xxx属性来储存图片的路径,在需要加载图片的时候,将data-xxx中图片的路径赋值给src,这样就 阅读详情

1. 原生实现

使用原生JS实现图片懒加载,都是借助几种不同的API,来判断当前图片是否在可视区域内。

1.1 通过监听滚动的方式

  • 图片顶部到文档顶部的距离 > 浏览器可视窗口高度 + 滚动条滚过的高度,此时的图片就是不可见的

  • 但如果用户直接滑到页面底部,那这个判断条件对所有的图片都为真

  • 还要加上一条判断:图片的高度 + 图片顶部到文档顶部的距离 > 滚动条滚过的高度,以确保图片在可视区域内,而不只是被滑过

  • 通过对应的API获取:

    • 待加载图片的高度:img.clientHeight
    • 图片顶部到文档顶部的距离:img.offsetTop
    • 浏览器窗口滚动过的距离:document.documentElement.scrollTop 或 document.body.scrollTop
    • 浏览器可视窗口高度:document.documentElement.clientHeight 或 window.innerHeight
    // 获取到所有的 img 标签对应的元素,存到 imgs 数组中
    const imgs = document.getElementsByTagName('img');
    function lazyLoad(imgs) {
      console.log('懒加载被触发了!')
      // 浏览器可视窗口的高度;
      const windowHeight = window.innerHeight;
      // 可视窗口滚动过的距离;
      const scrollHeight = document.documentElement.scrollTop;
      for (let i = 0; i < imgs.length; i++) {
        // 根据我们先前讲解过的是否可视逻辑进行判断;
        // !imgs[i].src 是当该图片已加载好之后,无需重复加载
        if (windowHeight + scrollHeight > imgs[i].offsetTop && !imgs[i].src && imgs[i].offsetTop + imgs[i].offsetHeight > scrollHeight) {
          // 使用data-xx的自定义属性可以通过dom元素的dataset.xx取得;
          imgs[i].src = imgs[i].dataset.src;
        }
      }
    };
    // 进入页面时执行一次加载;
    lazyLoad(imgs);
    // 监听滚动事件,进行图片懒加载;
    window.onscroll = () => lazyLoad(imgs);
    
  • 而这种方式实现懒加载需要进行防抖节流处理,更推荐采用节流的方式

    • 防抖需要用户完全停止滚动一定时间才能进行加载
    • 如果用户在查找指定图片而不松开控制滚动条的鼠标,很难保证完全不触发滚动事件
    • 这样就会导致无法触发懒加载函数,图片展示不出来
  • 而懒加载不能使用时间戳实现的节流,这会导致当快速滑到一个位置立刻停下时,无法进行图片的加载

    • 计时器需要等待单位时间计时器结束后才能执行一次函数
    • 时间戳只要判断当前时间间隔大于单位时间了就立即触发
    • 时间戳版本的节流函数,执行的是单位时间内函数的第一次触发;而计时器版本的节流函数,执行的是单位时间内函数的后一次触发
    function throttle(fn, delay, ...args) { // 使用剩余参数语法,接收任意数量的参数
      let timer = null; // 定义一个定时器
      return () => {
        let context = this; // 保存当前上下文
        if (!timer) { // 如果没有定时器
          timer = setTimeout(() => { // 设置一个延迟执行的定时器
            fn.apply(context, args); // 执行函数,并传入参数
            timer = null; // 清空定时器
          }, delay);
        }
      }
    }
    // 监听滚动事件,加载后面的图片;
    window.onscroll = throttle(lazyLoad, 500, imgs);
    

1.2 getBoundingClientRect

  • 该api返回值是一个 DOMRect对象,拥有left, top, right, bottom, x, y, width, 和 height属性

  • 当页面发生滚动的时候,top与left属性值都会随之改变

  • 如果一个元素在视窗内,会满足四个条件:

    • top >= 0
    • left >= 0
    • bottom <= 视窗高度
    • right <= 视窗宽度
    // Vue 组件中,为图片元素绑定监听滚动事件的方法
    <template>
      <div>
        <img v-for="(image, index) in images" :src="image" ref="lazyImages" @load="onImageLoad(index)" />
      </div>
    </template>
    //在组件的 methods 部分实现 onImageLoad 方法来检测图片是否进入可视区域
    <script>
    export default {
      methods: {
        onImageLoad(index) {
          const lazyImages = this.$refs.lazyImages;
          const img = lazyImages[index];
          const rect = img.getBoundingClientRect();
          const viewWidth = window.innerWidth||document.documentElement.clientWidth;
      	  const viewHeight = window.innerHeight||
      	  document.documentElement.clientHeight;
          if (rect.top <= viewWidth && rect.bottom <= viewHeight
          rect.top >= 0 && rect.left >= 0 && !img.src) {
            img.src = img.dataset.src;
          }
        },
      },
    };
    </script>
    

1.3 Intersection Observer

  • IntersectionObserver 是专门为检测某个元素是否出现在可视窗口

  • 以 IntersectionObserver 构造函数新建一个对象,接收两个参数callback和options

  • 当监听目标发生滚动变化时触发的回调函数,该回调函数接受一个参数 entries, 它是 IntersectionObserverEntry 的实例

  • 简单来讲这个 entries 就存储着我们用 observe() 添加给 observer 实例的那些需要被监听的元素与其根元素容器在某一特定过渡时刻的交叉状态(默认为顶级文档的视窗)

  • 而每一个 entry 有一个 target 属性,指向这个被监听的元素

    document.addEventListener("DOMContentLoaded", () => {
      if ("IntersectionObserver" in window) {
        const imgs = document.getElementsByTagName("img");
        const imageObserve = new IntersectionObserver((entries) => {
          entries.forEach((entry) => {
            // console.log("滚动触发监听函数了!")
            // 通过该属性判断元素是否出现在视口内
            if (entry.isIntersecting) {
              // entry.target能够取得那个dom元素
              const img = entry.target;
              img.src = img.dataset.src;
              // 图片加载完成后解除监听
              imageObserve.unobserve(img);
            }
          });
        });
        [...imgs].forEach((img) => {
          // 将所有的图片加入监听
          imageObserve.observe(img);
        });
      } else {
        alert("您的浏览器尚不支持IntersectionObserver,请尝试更新或者使用其他主流浏览器。");
      }
    });
    
  • 用户快速下滑到页面底部、直接从底部开始都不会触发上面图片的加载

2. 自定义指令

  • 将懒加载逻辑封装成可重用的指令,在需要懒加载的图片元素上使用该指令

    const lazyLoad = {
      // mounted 在绑定元素的父组件 
      // 及他自己的所有子节点都挂载完成后调用
      mounted(el, binding) {
        // 如果有需要可以先设置src为 loading 图 
        // el.setAttribute('src', 'loading 图的路径');
        const options = {
          rootMargin: '0px',
          threshold: 0.1,
        };
        const observer = new IntersectionObserver((entries) => {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              // binding 是一个对象,binding.value 是传递给指令的值
              el.setAttribute('src', binding.value);
              observer.unobserve(el);
            }
          });
        }, options);
        observer.observe(el);
      },
    };
    
    export default lazyLoad;
    

3. 移动端的lazyload属性

  • 原生的懒加载属性,只需在 img 标签上添加 loading="lazy" 属性,浏览器会自动处理图片的懒加载
  • 根据用户滚动操作至其元素附近执行加载,一定程度起到节流的作用

4. vue-lazyload

  • vue框架中可以安装的懒加载的插件,通过v-lazy指令的形式写到对应的元素实现懒加载

    <img v-lazy="img.thumbnail_pic_s">  // 用v-lazy替换src
    
  • 下载好依赖,并进行全局注册即可

  • src中的文件会被webpack编译,assets文件夹中的图片地址,会在编译过程中重命名

  • vue-lazyload是在main.js文件中引入,不会被webpack进行编译,因此vue-lazyload无法获得正确的图片地址,直接写相对地址就无法获取到图片正确地址

  • PS:如果设置了翻页功能,且每一页都是请求的数据进行渲染,会发现其他的数据都变了,唯独图片还是原来的图片,解决办法只要加个key就行

    <ul>  
        <li v-for="img in list">
            <img v-lazy="img.src" :key="img.src" >
        </li>
    </ul>
    
  • 这个库只支持在Vue2,在Vue3中main.js注册会报错

实现图片懒加载简单的方法 小编带大家了解一下为什么要实现图片懒加载? 其原理就是用户在打开页面时,图片会影响页面的打开速度,导致页面访问量不高,用户体验不好,一张图的大小就是几M,通俗的讲就是对网页性能的一种优化的方式,优先显示可视区的图片,当需要显示时,再发送图片请求,避免打开页面加载过多资源。 顶部 一张图便于我们理解js代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <me 阅读详情

相关推荐

ArcGIS实战:利用IDW反距离权重法实现气象数据的批量空间插值

本文详细介绍了如何利用ArcGIS中的IDW反距离权重法实现气象数据的批量空间插值。通过实战案例和脚本示例,展示了IDW插值在气象数据分析中的高效应用,包括算法原理、参数调优、批处理自动化及常见问题解决方案,帮助用户快速生成连续分布的气象地图。

weixin_29051149的博客 240

实现图片懒加载的5种方式

offsetTop(图像距离顶部的高度)-scrollTop(页面被卷去的高度)

maidu_xbd的博客 9763

Python爬虫实战:如何优雅地处理BOSS直聘的反爬机制与Cookie失效问题

本文详细介绍了如何通过Python爬虫技术优雅应对BOSS直聘的反爬机制与Cookie失效问题。从多账号轮换、动态请求头生成到代理IP管理,提供了一套完整的解决方案,帮助开发者构建稳定高效的数据采集系统,有效提升爬虫成功率与数据质量。

weixin_30733003的博客 1563

图片懒加载的四种实现方案

懒加载:延迟加载,对于一个很长的页面,优先加载可视区域的内容,其他部分等进入可视区域时再加载。

前端工程师 · Vue 生态深耕者,专注多端与工程化 9931

告别电源纹波!手把手教你用UCC28019设计一个高效率PFC模块(附完整原理图与BOM清单)

本文详细介绍了如何使用UCC28019设计高效率PFC模块,解决电源纹波问题。通过优化补偿网络、关键元器件选型及PCB布局,实现功率因数提升至0.99以上,降低输入电流谐波。附完整原理图与BOM清单,适用于电赛等快速开发场景。

weixin_42652674的博客 336

Cloudflare 5秒盾逆向实战:13次请求背后的Python补环境框架搭建指南

本文深入解析了如何通过Python构建浏览器环境模拟框架,以应对Cloudflare 5秒盾等现代Web防护机制。文章详细拆解了其背后复杂的13次请求链,涵盖了JavaScript执行引擎集成、DOM事件模拟、网络请求控制及Canvas指纹等环境检测的完整实现方案,为自动化数据采集和逆向工程提供了实战指南。

gold的博客 356

JS | 详解图片懒加载的6种实现方案

要实现图片的懒加载,核心的方法包括:利用JavaScript监听滚动事件、通过getBoundingClientRect()判断图片是否进入可视区域、使用Intersection Observer API、结合data属性暂存图片地址。在现代浏览器中,推荐使用Intersection Observer API来实现图片的懒加载,因为它相比传统的事件监听方式更为高效且易于维护。

青春木鱼的博客 6110

致远OA公文管理模块相关操作

致远oa协同办公系统 公文管理模板 相关操作

weixin_59666050的博客 4278

图片懒加载的原理--三种方法实现

3.设置img的默认src为一张1px*1px,很小很小的gif透明图片(所有的img都用这一张,只会发送一次请求),之所以需要是透明的,是需要透出通过background设置的背景图(一张loading.png,就是一个转圈圈的背景效果图)目前流行的做法是滚动动态加载,也就是懒加载,显示在屏幕之外的图片默认不加载,随着页面的滚动,图片进入了显示的范围,则触发图片的加载显示。5.等到图片进入视口后,利用js提取data-url的真实图片地址赋值给src属性,就会去发送请求加载图片,真正实现了按需加载。

weixin_43872282的博客 4960

YOLOv9改进策略【损失函数篇】| Slide Loss,解决简单样本和困难样本之间的不平衡问题

本文记录的是改进YOLOv9的损失函数,将其替换成Slide Loss,并详细说明了优化原因,注意事项等。Slide Loss函数可以有效地解决样本不平衡问题,为困难样本赋予更高的权重,使模型在训练过程中更加关注困难样本。若是在自己的数据集中发现容易样本的数量非常大,而困难样本相对稀疏,可尝试使用Slide Loss来提高模型在处理复杂样本时的性能。

Limiiiing的博客 2606

Python 爬虫实战:爬取微博热搜与用户评论数据

本文系统讲解微博热搜榜单与用户评论数据的爬取技术方案。针对微博热搜榜采用Requests+BeautifulSoup解析静态HTML结构,实现高效爬取;对于动态加载的评论数据,使用Selenium模拟浏览器行为规避反爬机制。详细阐述技术选型、反爬策略、数据清洗及存储方法,提供完整代码实现和输出示例。同时强调合规要求,提示开发者需在遵守平台规则的前提下进行数据采集。该方案为舆情分析和热点研究提供了可落地的技术实现路径。

2503_91057718的博客 1717

【前端】图片懒加载的原理和三种实现方式

图片懒加载的原理和实现方法

qq_44947815的博客 2万+

C语言程序设计——单词的统计和替换

【任务描述】 对任意一篇英文文章,统计其中每个单词分别出现了多少次,并可替换指定的单词。⑶ 对单词进行替换时,允许用户选择全部替换或逐个替换。替换完成后,将文章保存到文件。⑴ 英文文章以文件形式输入。⑵ 统计的结果保存到文件。

m0_60738889的博客 811

JavaScript 实现图片懒加载的三种常用方法

懒加载是一种对网页性能优化的方式,比如当访问一个网页的时候,优先显示可视区域的图片而不是一次加载全部的图片,当需要显示时,再发送请求加载图片。那么,如何使用懒加载来处理...

weixin_50999722的博客 3507

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

layui树形懒加载_layui实现图片懒加载延迟加载的方法

使用layui的图片懒加载,发现未加载的图片没有loading占位图,显示的是裂图,看着不是很好。找了一些解决方法我统一记录一下。layui图片懒加载使用方法layui.use(’flow’, function(){var flow = layui.flow;//当你执行这样一个方法时,即对页面中的全部带有lay-src的img元素开启了懒加载(当然你也可以指定相关img)flow.lazyimg...

weixin_39781594的博客 1122

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

实现图片懒加载的两种方法

懒加载及应用场景 懒加载是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示时,再发送图片请求,避免打开网页时加载过多资源。 当一个网站的加载图片过多时就需要懒加载的协助,页面图片多时,在首次载入时一次性加载会耗费时间长,使用懒加载可以使页面加载速度快、减轻服务器的压力、节省流量。 实现的思路:: 给目标元素指定一张占位图,将真实的图片链接存储在自定义属性中(data-), 监听scroll事件,当图片出现在可视区时,将data-src值赋值给src

Alice_yo的博客 4460

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

浅析图片懒加载(三种实现方法与两种优化方式)

今天我们就来康康图片懒加载(中间会涉及到`节流`的优化问题) 你将了解到`图片懒加载`的实现的三种方法(整体位置比较和视图位置和`observe`) 和优化的两种方式(`节流`和`IntersectionObserver`)

あなたの可愛い41 9939

JavaScript实现图片懒加载的三种常用方法总结

懒加载是一种对网页性能优化的方式,比如当访问一个网页的时候,优先显示可视区域的图片而不是一次加载全部的图片,当需要显示时,再发送请求加载图片。

qq_53895518的博客 2417

vue中实现图片懒加载的几种方法

vue中实现图片懒加载的几种方法,VueLazyLoad、v-lazy

m0_61663332的博客 1262

图片预加载和懒加载的实现方法

图片预加载即提前加载图片,可保证图片快速、无缝地发布,用户需要查看时可直接从本地缓存中渲染,适用于图片占据很大比例的网站。 方法1,在CSS background中加载:会增加页面的整体加载时间 #preload-01 { background: url(-01.png) no-repeat -9999px -9999px; } #preload-02 { background: url(-02.png) no-repeat -9999px -9999px; } 方法2,JS new image对象

前端小99的博客 726

动态渲染的html 实现图片懒加载,Javascript实现图片懒加载插件的方法

前言网络上各大论坛,尤其是一些图片类型的网站上,在图片加载时均采用了一种名为懒加载的方式,具体表现为,当页面被请求时,只加载可视区域的图片,其它部分的图片则不加载,只有这些图片出现在可视区域时才会动态加载这些图片,从而节约了网络带宽和提高了初次加载的速度,具体实现的技术并不复杂,下面分别对其说明。Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性...

weixin_28725949的博客 540

php程序懒加载图片,什么是懒加载?小程序中图片懒加载的两种实现方法

本篇文章给大家带来的内容是关于什么是懒加载?小程序中图片懒加载的两种实现方法 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。定义懒加载,前端人都知道的一种性能优化方式,简单的来说,只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。实现原理监听页面的scroll事件,判读元素距离页面的top值是否是小于等于页面的可视高度判断逻辑代码如下e...

weixin_42513170的博客 226

vue中实现图片懒加载的方法(一)

主要思路就是在可视区域内得图片进行加载,反之默认不做图片得请求,可以用我们本地自己定义得比较小得loading图代替(当然这个loading图片也会做网络请求,但是是我们自己定义的,那便可空,选的图会比较小,而且在同一时刻,相同图片只会请求一次),本次实现,源码里没有给默认的loading图片,而是把图片加载之前的样式,以及图片加载失败后的样式交给使用者自己定义。方案1: 传统实现图片懒加载,会去监听滚动条的变化,当图片进入可视区域内,通过监听当前图片以及滚动条位置,判断是否已经进入可视区域。

weixin_54145360的博客 8718

html页面图片延迟加载,实现图片懒加载的几种方法

懒加载就是延时加载,即当对象需要用到的时候再去加载。本文就来为大家介绍几种实现图片懒加载的方法,希望对大家有一定的帮助。懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片故问题拆分成两个:如何判断图片出现在了当前视口 (即如何判断我们能够看到图片)如何控制图片的加载方案一如何判断图片出现在了当前视口clientTop,offsetTop,clientHeight 以及 scroll...

weixin_36386044的博客 2711

css3讲解图片懒加载效果的实现方法,包括 HTML、CSS 和 JavaScript 的配合使用

前几天帮同事修老项目,打开页面差点被卡住——20张1MB的图片挤在首屏,加载条转得像电风扇。同事摸着发烫的电脑说:“客户投诉打开慢,可我也不想啊!” 别急,今天咱们就聊前端性能优化的“布洛芬”——**图片懒加载**。这招能让页面打开快30%,省流量还不卡,看完你也能给项目“降降温”~

前端大白话 1092
上一篇: Git常见命令 GitFlow
下一篇: 防抖与节流
ZoeLandia
博客等级 码龄6年 734粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值