【JavaScript】图片的懒加载
【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
html
的 clientHeight
是当前可视区域(viewport
)的高度。
document.documentElement.clientHeight
html
的 scrollTop
是当前滚动条距离 html
顶部的距离。
document.documentElement.scrollTop
向下滚动时,通过判断 图片距离 html
顶部的距离 小于了 上面二者的和,则说明进入了可视区域(或者在可视区域上方);总之不在下方(没滚动到的地方)。
所以问题就成了怎么获取 图片距离 html
顶部的距离。
元素ele
距离html
顶部的距离,可以通过 ele.offsetTop
属性获取,但是该属性是相对于 ele.offsetParent
的;而我们就需要一直递归到html/body
为止。
offsetParent
returnsnull
in the following situations:
- The element or its parent element has the
display
property set tonone
.- The element has the
position
property set tofixed
(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】图片的懒加载相关推荐
- 如何使用echo.js实现图片的懒加载(整理)
如何使用echo.js实现图片的懒加载(整理) 一.总结 一句话总结:a.在img标签中添加data-echo属性加载真实图片:<img class="loading" sr ...
- 图片的懒加载是怎么实现的
图片的懒加载是怎么实现的 为什么要使用懒加载? 对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,而代码也许就只有几十KB.当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载 ...
- 图片的懒加载和预加载?
一.写在前面 图片的懒加载和图片的预加载都是前端性能优化的一个方案,当然可能存在不同的应用场景,下面我们将总结一下这两个方案. 二.图片懒加载 图片的懒加载是什么? 图片的懒加载指的是在长网页中延迟加 ...
- jquery 当页面图片加载之后_图片的懒加载和预加载
一.懒加载 [1.1]什么是懒加载? 懒加载也就是延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式.当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1 ...
- JavaScript中的懒加载——概念,作用,原理,实现步骤,以及3种原生js实现方式
1.什么是懒加载? 懒加载也就是延迟加载. 当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图), 只有当图片出现在浏览 ...
- 图片的懒加载与预加载
懒加载 懒加载:也叫延迟加载,指的是在长网页中延迟加载图片的时机,当用户需要访问时,再去加载,这样可以提高网站的首屏加载速度,提升用户的体验,并且可以减少服务器的压力. 懒加载的实现原理是:将页面上图 ...
- php 页面加载图片卡,javascript,图片_js动态加载image导致浏览器很卡,javascript,图片 - phpStudy...
js动态加载image导致浏览器很卡 function addImage(logo,userid,name,style){ console.log("addImage"); var ...
- 图片懒加载和Vue路由懒加载
图片懒加载 什么是懒加载? 懒加载也叫做延迟加载或者按需加载 .在长网页中延迟加载暂时未看到的图片数据,能够优化网页性能,提高用户体验 .在较长的网页或应用中,如果图片很多,等待全部图片都被加载出来需 ...
- 聊一聊前端图片懒加载背后的故事
本文内容 什么是懒加载 如何实现懒加载 监听滚动事件 IntersectionObserver 浏览器原生方案 本文小结 相信大家已经注意到我博客有了一点变化,因为博主最近利用空闲时间对博客进行了优化 ...
最新文章
- 读“基于机器学习的无参考图像质量评估综述”有感
- 等宽矩阵(a)相乘a %*% x = b的逆运算solve(a,b)=x
- 用递归方法对二叉树进行先序、中序和后序遍历
- Tomcat 架构原理到架构设计,写得非常好!
- 蓝桥杯-区间k大数查询(java)
- 注意:匿名函数调用直接加载函数名setInterval(move,30)
- Excel 求差集和并集
- Linux 基本命令篇 - 计算机信息
- iOS Swift JSON解析教程
- 从面试官的角度聊聊培训班对程序员的帮助,同时给培训班出身的程序员一些建议
- 李兴平 越有人盯着360越会保护用户隐私
- JS匀速运动案例01
- python爬取豆瓣电影top250_【Python3爬虫教程】Scrapy爬取豆瓣电影TOP250
- OnLevelWasLoaded 弃用 Unity5.4 新方法 SceneManager.sceneLoaded
- 链接预测(Link Prediction)
- 将不规则时间段降雨量拆分合并到整点小时时间段
- org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].Standar
- VS调试出现错误提示 无法将“obj\Debug\*.*”复制到“bin\Debug\*.*”,文件正在由另一个进程使用,因此该进程无法访问此文件
- 读《逍遥游》感叹中国教育
- 《松鼠》电化教学教案
热门文章
- 墨尘的神经网络6--Alex Net模型代码复现及要点记录
- 计算机网络毕业设计关于flash,《电大计算机网络毕业论文FLASH爱好者网站;的网页设计与制作》.doc...
- 【pytesseract】python图片识别OCR库
- 浅谈民机软件适航宝典-DO-178
- 光电效应的历史:爱因斯坦与莱纳德之间的争斗
- 【技术方案】野外场景中的摄像头没有固定IP,如何联网实现视频监控需求?
- 95后阿里P7晒出工资单:狠补了这个,真香···
- Macbook pro 2015升级SSD
- App UI设计注意
- STC12C5A60S2最小系统板/51单片机温度显示和温度控制风扇