在js中图片的懒加载理解分析

本文深入解析懒加载技术,探讨其作为网页性能优化手段的重要性。介绍了懒加载的基本原理,包括延迟图片加载以提升用户体验,以及如何在代码中实现这一功能。同时,文章提供了具体的实现案例,涵盖html标记、JavaScript检测与加载机制,以及函数节流优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、懒加载的理解

  1. 懒加载:
    1)懒加载其实就是延迟加载,是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示的时候再发送图片请求,避免打开网页时加载过多资源
    2)在图片非常多的应用场景,为了提高页面加载速度,改善用户体验,我们对未出现在视野范围内的图片先不进行加载,等到出现在视野范围才去加载
    3)懒加载(LazyLoad)是前端优化的一种有效方式,极大的提升用户体验

  2. 懒加载的运用场景:
    1)当页面中需要一次性载入很多图片的时候,往往都是需要用懒加载的
    2)如果一次ajax请求数量过多的图片,把它们全部加载出来,会显示的很慢,对于用户的显示体验造成很大的影响

  3. 懒加载的原理:
    先把img的src指向空或者一个小图片,图片真实的地址存储在img一个自定义的属性里,< img src=”” data-src=”http://real.com/real.jpg” />,等到此图片出现在视野范围内了,获取img元素,把data-src里的值赋给src

  4. 判断元素是否在可视区域
    1)通过document.documentElement.clientHeight获取屏幕可视窗口高度
    通过element.offsetTop获取元素相对于文档顶部的距离
    通过document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离
    判断element.offsetTop - document.documentElement.scrollTop < document.documentElement.clientHeight是否成立,如果成立,元素就在可视区域内
    2)通过getBoundingClientRect()方法来获取元素的大小以及位置,这个方法返回一个名为ClientRect的DOMRect对象,包含了top、right、botton、left、width、height这些值
    bound.top<=clientHeight的时候,图片是在可视区域的
    封装代码如下:

function isInSight(el) {
  const bound = el.getBoundingClientRect();
  const clientHeight = window.innerHeight;
  //如果只考虑向下滚动加载
  //const clientWidth = window.innerWeight;
  return bound.top <= clientHeight + 100;
}

3)IntersectionObserver可以自动观察元素是否在视口内
可以用到intersectionRatio来判断是否在可视区域内,当intersectionRatio > 0 && intersectionRatio <= 1即在可视区域内
封装代码如下:

var io = new IntersectionObserver(callback, option);
// 开始观察
io.observe(document.getElementById('example'));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();
  1. 加载图片
    1)页面打开时需要对所有图片进行检查,是否在可视区域内,如果是就加载
    2)封装代码如下:
function checkImgs() {
  const imgs = document.querySelectorAll('.my-photo');
  Array.from(imgs).forEach(el => {
    if (isInSight(el)) {
      loadImg(el);
    }
  })
}

function loadImg(el) {
  if (!el.src) {
    const source = el.dataset.src;
    el.src = source;
  }

说明:优化的地方是设一个标识符标识已经加载图片的index,当滚动条滚动时就不需要遍历所有的图片,只需要遍历未加载的图片即可

  1. 函数节流优化
    1)在类似于滚动条滚动等频繁的DOM操作时,可以进行函数节流和函数去抖
    2)函数节流:让一个函数不要执行的太频繁,减少一些过快的调用来节流
    3)基本步骤:
    获取第一次触发事件的时间戳
    获取第二次触发事件的时间戳
    时间差如果大于某个阈值就执行事件,然后重置第一个时间
    4)封装代码如下:
function throttle(fn, mustRun = 500) {
  const timer = null;
  let previous = null;
  return function() {
    const now = new Date();
    const context = this;
    const args = arguments;
    if (!previous){
      previous = now;
    }
    const remaining = now - previous;
    if (mustRun && remaining >= mustRun) {
      fn.apply(context, args);
      previous = now;
    }
  }
}

说明:mustRun就是调用函数的时间间隔,无论多么频繁的调用fn,只有remaining>=mustRun时fn才能被执行

二、懒加载的实现

  1. 简单的懒加载实现
    1)html 部分:
<!--data-* 全局属性:构成一类名称为自定义数据属性的属性,可以通过HTMLElement.dataset来访问-->

<img src="" data-src="./images/1.jpg" >
<img src="" data-src="./images/2.jpg" >
<img src="" data-src="./images/3.jpg" >
<img src="" data-src="./images/4.jpg" >
<img src="" data-src="./images/5.jpg" >
<img src="" data-src="./images/6.jpg" >
<img src="" data-src="./images/7.jpg" >
<img src="" data-src="./images/8.jpg" >

2)js部分:

window.onload = function(){
        // 获取元素
        var img = document.querySelectorAll("img");
        var len = img.length;
        // 存储图片的加载位置
        var n = 0;

        // 获取图片的可视区域
        var height = document.documentElement.clientHeight;
        var top = document.body.scrollTop || document.documentElement.scrollTop;
        for(var i=n;i<len;i++){
            if(img[i].offsetTop< height + top){
                if(img[i].getAttribute("src")==""){
                    img[i].src = img[i].getAttribute("data-src");
                }
                n = i + 1;
                console.log("第"+n+"张图片"+",n="+n);
            }
        }
    };

3)在当打开页面的时候
console 控制台输出:
在这里插入图片描述

network 网络输出:
在这里插入图片描述

4)在打开页面滚动的时候
console 控制台输出:
在这里插入图片描述
network 网络输出:
在这里插入图片描述
5)通过在打开页面的时候,网页中的图片是没有全部加载出来的,从network中可以看出只加载出了两张图片资源。在打开页面进行滚动以后,后面的图片资源才慢慢加载出来,在network中看出,但是也只是展示出了五张图片的资源,展示出了我们的可视区域,剩下的图片也是没有加载出来,这样恰恰就可以实现了图片的懒加载,保证一次请求不会请求所有的资源,在出现可视区域后才会加载出来,提高了前端的性能优化

  1. 懒加载的封装函数
    1)代码如下:
function checkImgs() {
  const imgs = Array.from(document.querySelectorAll(".my-photo"));
  imgs.forEach(item => io.observe(item));
}

function loadImg(el) {
  if (!el.src) {
    const source = el.dataset.src;
    el.src = source;
  }
}

const io = new IntersectionObserver(ioes => {
  ioes.forEach(ioe => {
    const el = ioe.target;
    const intersectionRatio = ioe.intersectionRatio;
    if (intersectionRatio > 0 && intersectionRatio <= 1) {
      loadImg(el);
    }
    el.onload = el.onerror = () => io.unobserve(el);
  });
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值