【JavaScript】图片的懒加载

文章目录

  • 【JavaScript】图片的懒加载
    • 1. 懒加载
    • 2. 利用`scroll`事件
      • 利用`HTMLElement.offsetTop`
      • 利用`Element.getBoundingClientRect()`
      • 节流优化
    • 3. 利用`IntersectionObserver`
    • 4. References

1. 懒加载

在一个很长很长的页面里,只渲染可视区域里的内容对于性能提升非常有用。图片懒加载就是这样一种技术,我们可以在图片进入可视区域之后再去请求/渲染。

这需要一个技巧,就是暂时不给 <img> 标签的 src 属性赋值,需要加载时再赋值。

<img src="" data-src="xxx.jpg">

我们利用[data-src] 来标记好图片来源,等图片进入可视区域时,将其赋值给 src 即可。

img.src = img.dataset.src;

于是,问题的难点成了如何判断 图片有没有进入可视区域

2. 利用scroll事件

显然,我们需要滚动触发加载。

利用HTMLElement.offsetTop

htmlclientHeight 是当前可视区域(viewport)的高度。

document.documentElement.clientHeight

htmlscrollTop 是当前滚动条距离 html 顶部的距离。

document.documentElement.scrollTop

向下滚动时,通过判断 图片距离 html 顶部的距离 小于了 上面二者的和,则说明进入了可视区域(或者在可视区域上方);总之不在下方(没滚动到的地方)。

所以问题就成了怎么获取 图片距离 html 顶部的距离

元素ele距离html顶部的距离,可以通过 ele.offsetTop 属性获取,但是该属性是相对于 ele.offsetParent 的;而我们就需要一直递归html/body为止。

offsetParent returns null in the following situations:

  • The element or its parent element has the display property set to none.
  • The element has the position property set to fixed (firefox returns <body>).
  • The element is <body> or <html>.

HTMLElement.offsetParent - Web APIs | MDN

根据描述,当递归到 body 时会返回 null

    function getOffsetTopFromRoot(ele) {let top = ele.offsetTop;while (ele = ele.offsetParent) {top += ele.offsetTop;}return top;}

所以得到进入视口的条件为 getOffsetTopFromRoot(img) <= clientHeight + scrollTop

    const images = document.querySelectorAll('img');const loadImage = (img) => img.src ||= img.dataset.src;function lazyLoadImage(img) {const clientHeight = document.documentElement.clientHeight;const scrollTop = document.documentElement.scrollTop;if (getOffsetTopFromRoot(img) <= clientHeight + scrollTop) {loadImage(img);}}function loadImages() {images.forEach(img => {lazyLoadImage(img);})}loadImages();window.addEventListener('scroll', loadImages);

实现了,但是,这,也太麻烦了吧。

利用Element.getBoundingClientRect()

其实。浏览器提供了一个获取元素相对于视口的距离信息的API

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置

Element.getBoundingClientRect() - Web API 接口参考 | MDN

既然如此,我们很容易得到判断条件为 img.getBoundingClientRect().top <= clientHeight,上述代码替换掉条件即可。

节流优化

针对事件触发,可以做节流优化。

    function throttle(func, delay) {let timer = null;return function () {if (!timer) {timer = setTimeout(() => {func();timer = null;}, delay);}}}const loadImages = throttle(() => {images.forEach(img => {lazyLoadImage(img);})}, 500);

3. 利用IntersectionObserver

上述方法存在性能问题,怪异且不优雅。于是有了专门的API

Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。

Intersection Observer API - Web API 接口参考 | MDN

IntersectionObserver 甚至为我们提供好了 entry.intersectionRatio 来获取出现在视口里的比例,在0-1之间,于是我们只需要判断 entry.intersectionRatio > 0 即可

    const images = document.querySelectorAll('img');const loadImage = (img) => img.src ||= img.dataset.src;const observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.intersectionRatio > 0) {loadImage(entry.target);}})});images.forEach(img => {observer.observe(img);})

4. References

  • Intersection Observer API - Web API 接口参考 | MDN
  • IntersectionObserver API 使用教程 - 阮一峰的网络日志
  • 原生js实现图片懒加载(lazyLoad) - 知乎
  • HTMLElement.offsetParent - Web APIs | MDN
  • Element.getBoundingClientRect() - Web API 接口参考 | MDN

【JavaScript】图片的懒加载相关推荐

  1. 如何使用echo.js实现图片的懒加载(整理)

    如何使用echo.js实现图片的懒加载(整理) 一.总结 一句话总结:a.在img标签中添加data-echo属性加载真实图片:<img class="loading" sr ...

  2. 图片的懒加载是怎么实现的

    图片的懒加载是怎么实现的 为什么要使用懒加载? 对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,而代码也许就只有几十KB.当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载 ...

  3. 图片的懒加载和预加载?

    一.写在前面 图片的懒加载和图片的预加载都是前端性能优化的一个方案,当然可能存在不同的应用场景,下面我们将总结一下这两个方案. 二.图片懒加载 图片的懒加载是什么? 图片的懒加载指的是在长网页中延迟加 ...

  4. jquery 当页面图片加载之后_图片的懒加载和预加载

    一.懒加载 [1.1]什么是懒加载? 懒加载也就是延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式.当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1 ...

  5. JavaScript中的懒加载——概念,作用,原理,实现步骤,以及3种原生js实现方式

    1.什么是懒加载? 懒加载也就是延迟加载. 当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图), 只有当图片出现在浏览 ...

  6. 图片的懒加载与预加载

    懒加载 懒加载:也叫延迟加载,指的是在长网页中延迟加载图片的时机,当用户需要访问时,再去加载,这样可以提高网站的首屏加载速度,提升用户的体验,并且可以减少服务器的压力. 懒加载的实现原理是:将页面上图 ...

  7. php 页面加载图片卡,javascript,图片_js动态加载image导致浏览器很卡,javascript,图片 - phpStudy...

    js动态加载image导致浏览器很卡 function addImage(logo,userid,name,style){ console.log("addImage"); var ...

  8. 图片懒加载和Vue路由懒加载

    图片懒加载 什么是懒加载? 懒加载也叫做延迟加载或者按需加载 .在长网页中延迟加载暂时未看到的图片数据,能够优化网页性能,提高用户体验 .在较长的网页或应用中,如果图片很多,等待全部图片都被加载出来需 ...

  9. 聊一聊前端图片懒加载背后的故事

    本文内容 什么是懒加载 如何实现懒加载 监听滚动事件 IntersectionObserver 浏览器原生方案 本文小结 相信大家已经注意到我博客有了一点变化,因为博主最近利用空闲时间对博客进行了优化 ...

最新文章

  1. 读“基于机器学习的无参考图像质量评估综述”有感
  2. 等宽矩阵(a)相乘a %*% x = b的逆运算solve(a,b)=x
  3. 用递归方法对二叉树进行先序、中序和后序遍历
  4. Tomcat 架构原理到架构设计,写得非常好!
  5. 蓝桥杯-区间k大数查询(java)
  6. 注意:匿名函数调用直接加载函数名setInterval(move,30)
  7. Excel 求差集和并集
  8. Linux 基本命令篇 - 计算机信息
  9. iOS Swift JSON解析教程
  10. 从面试官的角度聊聊培训班对程序员的帮助,同时给培训班出身的程序员一些建议
  11. 李兴平 越有人盯着360越会保护用户隐私
  12. JS匀速运动案例01
  13. python爬取豆瓣电影top250_【Python3爬虫教程】Scrapy爬取豆瓣电影TOP250
  14. OnLevelWasLoaded 弃用 Unity5.4 新方法 SceneManager.sceneLoaded
  15. 链接预测(Link Prediction)
  16. 将不规则时间段降雨量拆分合并到整点小时时间段
  17. org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].Standar
  18. VS调试出现错误提示 无法将“obj\Debug\*.*”复制到“bin\Debug\*.*”,文件正在由另一个进程使用,因此该进程无法访问此文件
  19. 读《逍遥游》感叹中国教育
  20. 《松鼠》电化教学教案

热门文章

  1. 墨尘的神经网络6--Alex Net模型代码复现及要点记录
  2. 计算机网络毕业设计关于flash,《电大计算机网络毕业论文FLASH爱好者网站;的网页设计与制作》.doc...
  3. 【pytesseract】python图片识别OCR库
  4. 浅谈民机软件适航宝典-DO-178
  5. 光电效应的历史:爱因斯坦与莱纳德之间的争斗
  6. 【技术方案】野外场景中的摄像头没有固定IP,如何联网实现视频监控需求?
  7. 95后阿里P7晒出工资单:狠补了这个,真香···
  8. Macbook pro 2015升级SSD
  9. App UI设计注意
  10. STC12C5A60S2最小系统板/51单片机温度显示和温度控制风扇