我的编程空间,编程开发者的网络收藏夹
学习永远不晚

前端JS图片懒加载原理是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

前端JS图片懒加载原理是什么

这篇文章主要介绍“前端JS图片懒加载原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“前端JS图片懒加载原理是什么”文章能帮助大家解决问题。

原理

图片懒加载的原理是没有在可视区域的图片暂时不加载图片,等进入可视区域后在加载图片,这样可以减少初始页面加载的图片数量而提升页面加载速度。 图片懒加载在提升页面加载速度的同时也会伴随用户看其他未展示的图片时会有等待时间;图片加载显示会伴有布局抖动等问题。

方案

图片懒加载的关键是:判断一个元素是否在可视区域。

方案一:img的loading属性设为“lazy”

HTMLImageElement 的 loading 属性为一个字符串,它的值会提示 用户代理 告诉浏览器不在可视视口内的图片该如何加载。这样一来,通过推迟图片加载仅让其在需要的时候加载而非页面初始载入时立刻加载,优化了页面的载入。

lazy 告诉用户代理推迟图片加载直到浏览器认为其需要立即加载时才去加载。例如,如果用户正在往下滚动页面,值为 lazy 会导致图片仅在马上要出现在 可视视口中时开始加载。

使用方法
<img class="lazy" data-src="xxx.jpg" loading="lazy" />
优点

只设置一个属性不用 JavaScript 控制代码是最简单方便的方案,性能也是比较好的。

兼容性

前端JS图片懒加载原理是什么

大部分主流浏览器都兼容该属性。

缺点

虽然整个方案简单性能好,但问题也是最多的,所以很少使用这种方案。

  • 前面提到图片懒加载用户看其他未展示的图片时会有等待时间,一般会设置一个默认图片,这种方案不能设置默认图片

  • 图片的加载数量和图片的布局、可视区域尺寸有关,难以控制

  • 图片的加载顺序也难以控制

该方案能粗略的实现图片懒加载基本功能。

方案二:通过offsetTop来计算是否在可视区域内

可视区域高度是 document.documentElement.clientHeight ,而可视区域的位置是在滚动条滚动位置 scrollTopscrollTop+document.documentElement.clientHeight之间。因此通过 image.offsetTop <= document.documentElement.clientHeight + document.documentElement.scrollTop 判断图片是否可以在可视区域内。

  function lazyload() {        var lazyImages = document.querySelectorAll(".lazyload");        lazyImages.forEach(function (image) {          if ( image.offsetTop <= document.documentElement.clientHeight + document.documentElement.scrollTop) {            image.class="lazy" data-src = image.getAttribute("data-class="lazy" data-src");          }        });      }

添加滚动条监听。

  window.onscroll = function () {        lazyload();};

html结构。

 <img class="lazy" data-src="./default.gif" class="lazyload" data-class="lazy" data-src="./photo-1.jpg" />
优化

上面只是简单的实现图片懒加载,在实际开发中还要很多细节需要优化: 首先是兼容性,这里有两个点涉及到兼容性:document.documentElement.clientHeightdocument.documentElement.scrollTop 。 获取浏览器窗口的内部高度方法有 window.innerHeightdocument.documentElement.clientHeightwindow.innerHeight兼容性是 ie9+ 和其他主流浏览器。

前端JS图片懒加载原理是什么

document.documentElement.clientHeight 浏览器都支持。

前端JS图片懒加载原理是什么

获取滚动位置方法有 window.pageYOffsetdocument.documentElement.scrollTopwindow.pageYOffset 兼容性是 ie9+ 和其他主流浏览器。

前端JS图片懒加载原理是什么

第二优化点是offsetTop。

offsetParent 元素有滚动条的情况下计算会不会有问题

HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。 &mdash;&mdash;MDN

offsetTop 是相对其 offsetParent 元素的并不是相对浏览器窗口可视区域的。如果图片元素有 offsetParent 那么 offsetTop 是有偏差的。

      function getBoundingClientTop(el) {        let top = el.offsetTop;        let parent = el.offsetParent;        while (parent) {          top += parent.offsetTop;          parent = parent.offsetParent;        }        return top;      }

第三优化点避免赋值 class="lazy" data-src 。 代码是通过 lazyload 类获取需要懒加载的元素,这样会把之前已经加载图片的元素也获取到了,而重复设置 class="lazy" data-src属性。

   function lazyload() {        var lazyImages = document.querySelectorAll(".lazyload[data-class="lazy" data-src]");        lazyImages.forEach(function (image) {          if (            getBoundingClientTop(image) <=            document.documentElement.clientHeight +              document.documentElement.scrollTop          ) {            image.class="lazy" data-src = image.getAttribute("data-class="lazy" data-src");            image.removeAttribute("data-class="lazy" data-src")          }        });      }

通过 lazyload 类并且有 data-class="lazy" data-src 来获取元素,class="lazy" data-src 设置完后移除 data-class="lazy" data-src 属性来避免重复设置 class="lazy" data-src 。

第四优化点 onscroll 是否添加防抖。 onscroll 常用的优化点是加入防抖来减少事件触发的频率,但这里如果加了防抖,计算元素是否在可视区域内的精度就差很多,当滚动速度比较快的情况下加载反应不灵敏,这里就要找平衡点。

第五优化点页面中局部的 div 滚动图片懒加载。 除了整个页面的滚动图片懒加载,也有页面中局部滚动图片懒加载,就需要给制定的有滚动条 dom 元素绑定onscroll 事件。

    class="lazy" data-srcollDom.onscroll = function () {        lazyload();      };

并且获取图片 top 是相对有滚动条 dom 元素

getBoundingClientTop(image)-getBoundingClientTop(class="lazy" data-srcollDom) <= class="lazy" data-srcollDom.clientHeight + class="lazy" data-srcollDom.scrollTop

第六优化点加载图片的时间点提前。 代码中是图片元素进入可视区域后才加载图片,用户就需要等待一段时间才能看到图片显示出来,如果把图片加载时间提前,图片元素距离可视区域一定范围内就加载图片,那么用户等待时间就会减少一些。

优点

兼容性好,各个环节可以控制。

缺点

性能相对不是很好,滚动事件频繁触发,并且获取元素的位置信息,可能会强行触发重排和重绘导致一定的性能消耗。

方案三:通过getBoundingClientRect来计算是否在可视区域内

大致思路和方案二一样只是把获取图片元素 offsetTop 改成 getBoundingClientRect 方法获取离可视区顶端的距离。比方案一要简单一点,缺点也和方案一一样。

方案四:使用IntersectionObserver来判断是否在可视区域内

该方案是通过 IntersectionObserver 来判断图片元素是否在可视区域内。

IntersectionObserver() 构造器创建并返回一个 IntersectionObserver 对象。如果指定 rootMargin 则会检查其是否符合语法规定,检查阈值以确保全部在 0.0 到 1.0 之间,并且阈值列表会按升序排列。如果阈值列表为空,则默认为一个 [0.0] 的数组。 &mdash;&mdash; MDN

完全没看懂mdn的这段解释,简单说就是

IntersectionObserver 接口提供了一种异步观察目标元素与祖先元素或顶级文档 viewport 的交集中的变化的方法。祖先元素与视窗viewport被称为根(root)。

      var images = document.querySelectorAll(".lazyload");      var io = new IntersectionObserver(        function (entries) {          entries.forEach((item) => {            // isIntersecting是一个Boolean值,判断目标元素当前是否可见            if (item.isIntersecting) {              item.target.class="lazy" data-src = item.target.dataset.class="lazy" data-src;              // 图片加载后即停止监听该元素              io.unobserve(item.target);            }          });        }      );      images.forEach(function(image){        io.observe(image)      })

IntersectionObserver 的监听对于页面局部滚动条也是有效的,不用再单独对局部滚动条进行处理。 而提前加载图片通过配置 rootMargin 来扩大监听区域。

      var images = document.querySelectorAll(".lazyload");      var io = new IntersectionObserver(        function (entries) {          entries.forEach((item) => {            // isIntersecting是一个Boolean值,判断目标元素当前是否可见            if (item.isIntersecting) {              item.target.class="lazy" data-src = item.target.dataset.class="lazy" data-src;              // 图片加载后即停止监听该元素              io.unobserve(item.target);            }          });        },        {          root: null,          rootMargin: "0px 0px 300px 0px",        }      );      images.forEach(function(image){        io.observe(image);      })
兼容性

前端JS图片懒加载原理是什么

在一些低版本浏览器中还存在一些问题。

优点

性能好,简单。

缺点

低版本浏览器 IntersectionObserver 存在问题,不支持 IE。

问题

布局抖动

布局抖动是因为开始图片没有宽高,内容显示出来后有了宽高导致位置变动。带来的影响主要是用户体验不好,用户的注意力已经锁定了某个区域准备阅读,突然那个区域下移了,中断阅读而重新定位。可以直接在 img 标签上设置要加载图片的宽高。

<img class="lazy" data-src="blank.gif" data-class="lazy" data-src="normal.jpg"  />

解决问题:方案解决的问题范围是图片宽高固定的情况,在响应式环境图片宽高不确定下不适用。

用户体验:img的默认占位图是一个loading或是灰色背景,图片还没加载的体验。

响应式图片

虽然响应式下图片的宽高会变,但是图片的宽高比是不变的,图片的宽高比变了图片也就变形了。所以 img 标签设定图片宽高比,就能根据不同视图的宽度算出不同高度。 先创建一个宽高比为 5:1 的 div。

   <div ></div>

padding 为百分比是相对自身宽度的百分比。 然后再创建了一个宽高比为 5:1 的 img。

    <div >        <img >      </div>

这样就能适应响应式的宽度改变,这种方式叫 Aspect Ratio Boxes。 占位图片可以设置成原图片的小尺寸图片,被放大后图片变模糊,这样开始加载小图片但图片的轮廓出现,后面在加载大图片显示清晰,给用户的体验是图片开始就在加载,然后加载完成就变清晰了。 img 标签 class="lazy" data-srcset 属性是处理响应式图片的。懒加载中可以设置 data-class="lazy" data-srcset 来延迟修改 class="lazy" data-srcset 属性。

SEO不友好

<img> 标签中的 class="lazy" data-src 属性携带的仍然是原始大小的图片确保了站外 SEO、社会化分享、RSS 等不会读不到原图。Aspect Ratio Boxes 方式使占位图片适应响应式,class="lazy" data-srcset 属性存放了一张原图的小尺寸缩略图阻止 class="lazy" data-src 原图的加载而加载缩略图优化加载体验,最后延迟将 data-class="lazy" data-srcset 的值赋值到 class="lazy" data-srcset 中。

插件

  • lazyload.js 是 IntersectionObserver 方式,而且当浏览器不支持 IntersectionObserver 的时候就直接加载图片,没有延迟加载的功能。

  • vue-lazyload 使用 IntersectionObserver 和 getBoundingClientRect 方式,默认 getBoundingClientRect 方式懒加载,里面的一些封装细节有很多有意思的地方,不止绑定了 onscroll 事件还绑定了 'onwheel'、'onmousewheel'、'onresize'、 'onanimationend'、'ontransitionend'、'ontouchmove'问什么要绑定这么多事件,插件为什么默认 getBoundingClientRect 方式而不用 IntersectionObserver 方式,待下回分解。

  • react-lazyload 只用了 getBoundingClientRect 方式,里面的封装细节也很有意思。

关于“前端JS图片懒加载原理是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

前端JS图片懒加载原理是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

前端JS图片懒加载原理是什么

这篇文章主要介绍“前端JS图片懒加载原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“前端JS图片懒加载原理是什么”文章能帮助大家解决问题。原理图片懒加载的原理是没有在可视区域的图片暂时不加载
2023-07-05

前端图片懒加载的原理与3种实现方式举例

图片懒加载又称图片延时加载、惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力,下面这篇文章主要给大家介绍了关于前端图片懒加载的原理与3种实现方式的相关资料,需要的朋友可以参考下
2023-03-01

web前端图片懒加载的原理与实现方式有哪些

这篇文章主要讲解了“web前端图片懒加载的原理与实现方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web前端图片懒加载的原理与实现方式有哪些”吧!一. 图片懒加载的目的大型网站如常
2023-07-05

js怎么实现图片的懒加载

这篇文章给大家分享的是有关js怎么实现图片的懒加载的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。图片的懒加载是前端优化必须要掌握的东西,图片实现懒加载可以节省带宽又可以减轻我们网页的负荷。接下来我来记录一下我所掌
2023-06-14

JS图片懒加载库VueLazyLoad怎么使用

这篇文章主要介绍“JS图片懒加载库VueLazyLoad怎么使用”,在日常操作中,相信很多人在JS图片懒加载库VueLazyLoad怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JS图片懒加载库Vue
2023-07-05

VUE懒加载原理详解:一文带你读懂图片懒加载的奥秘

懒加载是一种通过延迟加载资源,以提高网页加载速度和性能的技术。它可以有效减少初始页面加载时间,从而提高用户体验和网站排名。本文将详细讲解 VUE 懒加载的原理,帮助您理解图片懒加载的奥秘。
VUE懒加载原理详解:一文带你读懂图片懒加载的奥秘
2024-02-13

java懒加载的实现原理是什么

Java的懒加载(Lazy Loading)是一种延迟加载的策略,即在需要使用某个对象时才进行实例化和初始化,在之前不会占用额外的资源。懒加载的实现原理主要通过使用单例模式和双重检查锁定(Double-Checked Locking)来实现
2023-09-14

JS前端instanceof的实现原理是什么

这篇文章主要介绍了JS前端instanceof的实现原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JS前端instanceof的实现原理是什么文章都会有所收获,下面我们一起来看看吧。instanceo
2023-07-04

JS前端使用迭代器和生成器原理是什么

这篇文章主要介绍了JS前端使用迭代器和生成器原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JS前端使用迭代器和生成器原理是什么文章都会有所收获,下面我们一起来看看吧。正文生成器和迭代器这两个东西平时作
2023-07-05

Android图片加载库Glide用法是什么

这篇文章主要讲解了“Android图片加载库Glide用法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android图片加载库Glide用法是什么”吧!Glide介绍Glide是一个
2023-06-22

unity异步加载原理是什么

Unity的异步加载原理是利用协程(Coroutine)和异步操作(AsyncOperation)来实现的。在Unity中,协程是一种特殊的函数,可以在执行到一定点时暂停,并在后续某个时刻继续执行。协程可以通过使用yield return语
2023-09-29

require加载器的原理是什么

这篇文章给大家介绍require加载器的原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1.node模块化的实现node中是自带模块化机制的,每个文件就是一个单独的模块,并且它遵循的是CommonJS规范,也就
2023-06-14

Android图片框架Glide原理是什么

本篇内容主要讲解“Android图片框架Glide原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android图片框架Glide原理是什么”吧!首先引入依赖 implementa
2023-07-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录