懒加载预加载

(一)、懒加载

1.什么是懒加载?

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

只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。这就是图片懒加载。

2.为什么要使用懒加载?

很多页面,内容很丰富,页面很长,图片较多。比如说各种商城页面。这些页面图片数量多,而且比较大,少说百来K,多则上兆。要是页面载入就一次性加载完毕。估计大家都会等到黄花变成黄花菜了。

3.懒加载的优点是什么?

页面加载速度快、可以减轻服务器的压力、节约了流量,用户体验好

4.懒加载的原理是什么?

页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片,只有通过javascript设置了图片路径,浏览器才会发送请求。

懒加载的原理就是先在页面中把所有的图片统一使用一张占位图进行占位,把真正的路径存在元素的“data-url”(这个名字起个自己认识好记的就行)属性里,要用的时候就取出来,再设置;

5.懒加载的实现步骤?

1)首先,不要将图片地址放到src属性中,而是放到其它属性(data-original)中。

2)页面加载完成后,判断图片是否在用户的视野内,如果在,则将data-original属性中的值取出存放到src属性中。

6、懒加载实现方式

html结构

1、 obj.getAttribute("属性名")通过元素节点的属性名称获取属性的值。

2、使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放, dataset 获取自定义属性值的使用

<ul>
    <li>
      <img data-src="./img/img1.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img2.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img3.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img4.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img5.png" src="./img/loading.gif" alt="" />
    </li>
  </ul>
第一种

元素距顶部的高度 - 页面被卷去的高度 <= 浏览器可视区的高度)

来判断是否符合我们想要的条件.需要实时监听页面滚动时 图片的高度变化

<script>
        window.onload = function () {
          var imgs = document.querySelectorAll("img");
          // 初始化执行
          lazyLoad(imgs);
          // 滚动执行
          window.addEventListener("scroll", function () {
            lazyLoad(imgs);
          });
  
          function lazyLoad(imgs) {
            for (let i = 0; i < imgs.length; i++) {
              var imgoffsetT = imgs[i].offsetTop; // 图片的距顶部的高度
              var wheight = window.innerHeight; // 浏览器可视区的高度
              var scrollT = document.documentElement.scrollTop; // 页面被卷去的高度
              if (imgoffsetT - scrollT <= wheight) {
                // 判断图片是否将要出现
                imgs[i].src = imgs[i].dataset.src; // 出现后将自定义地址转为真实地址
              }
            }
          }
        };
      </script>
第二种

getBoundingClientRect()

——获取元素位置,这个方法没有参数

——用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。

——是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。

该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;

window.onload = function () {
  var imgs = document.querySelectorAll("img");
  // 初始调动一次
  lazyLoad();
  // 监听滚动时,再调用函数
  window.addEventListener("scroll", throttle(lazyLoad, 1000), false);


  //函数1:封装判定图片是否在可视区
  function isInVisibleArea(imgOne) {
    const info = imgOne.getBoundingClientRect();
    //  获取页面可视区的高度,宽度
    let windowH = window.innerHeight;
    let windowW = window.innerWidth;
    // 限定参数在可视区内
    let res = info.bottom > 0 && info.top < windowH && info.right > 0 && info.left < windowW;
    return res;
  }

  //函数2: 封装滚动时重新加载函数
  function lazyLoad() {
    for (let i = 0; i < imgs.length; i++) {
      const imgOne = imgs[i];
      // 判定是否在可视区内
      if (isInVisibleArea(imgOne)) {
        // 替换src方法一:
        // imgOne.src = imgOne.getAttribute("data-src");
        // 替换src方法二:
        imgOne.src = imgOne.dataset.src;
        // imgs.splice(i,1)
        // i--;
      }
      console.log("我滚了"); //滚动就出发,要做节流操作
    }
  }

  //函数3:节流函数
  function throttle(fn, time = 250) {
    let lastTime = null;
    return function (...args) {
      const now = Date.now(); //当前时间
      if (now - lastTime >= time) {
        fn(); //帮助执行函数,改变上下文
        lastTime = now;
      }
    };
  }
};
第三种

IntersectionObserver(callback)

callback函数会触发两次,元素进入视窗(开始可见时)和元素离开视窗(开始不可见时)都会触发

<script>
        const imgs = document.querySelectorAll("img");
        var callback = function (res) {
          //res 是观察的元素数组   info 每个被观察的图片信息
          res.forEach(function (info) {
            //  isIntersecting 目标是否被观察到,返回布尔值
            if (info.isIntersecting) {
              // img 就是当前的图片标签
              const img = info.target;
              img.src = img.getAttribute("data-src");
              // 真实地址替换后 取消对它的观察
              obs.unobserve(img);
             // console.log("触发");
            }
          });
        };
  
        // 实例化 IntersectionObserver
        const obs = new IntersectionObserver(callback);
        // 遍历imgs所有的图片,然后给每个图片添加观察实例
        imgs.forEach(function (img) {
          //  observe : 被调用的IntersectionObserver实例。给每个图片添加观察实例
          obs.observe(img);
        });
      </script>

(二)、预加载

1.什么是预加载

资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。预加载简单来说就是将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。

2.为什么要用预加载

在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,直到所有内容加载完毕。

3、预加载实现方式

html结构

<!-- 需求:实现点击图片,切换下一张图片 -->
    <div>
      <p></p>
      <img src="./img/img1.gif" alt="" />
    </div>

js实现

<script>
      const imgs = ["./img/img2.gif", "./img/img3.gif", "./img/img4.gif", "./img/img5.png"];
      const img = document.querySelector("img");
      const test = document.querySelector("p");
      //实现点击切换下一张图片
      let index = 0;
      test.innerHTML = "我是第" + (index + 1) + "张图片";
      img.addEventListener("click", function () {
        if (index < imgs.length) {
          img.src = imgs[index];
          index++;
          test.innerHTML = "我是第" + (index + 1) + "张图片";
        }else{
          alert('没有了')
        }

        // 切换图片后,同时让浏览器提前加载下载一张图片
        if (index < imgs.length) {
          preLoad(imgs[index]);
        }
      });

      // 调用加载函数,页面一开始就加载数组第一个元素
      preLoad(imgs[0]);
      
      // 封装函数,新建一个img标签,然后增加src属性,让浏览器加载下一张图片
      function preLoad(src) {
        img.addEventListener("load", () => {
          // 创建一个新的img标签
          const img = document.createElement("img");
          // 给img添加src属性,为我们传进来的src
          img.src = src;
        });
      }
    </script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/982435.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 中的析构函数:对象生命周期的终结艺术

在 Python 的面向对象编程中&#xff0c;析构函数是一个重要的概念。它主要用于在对象被销毁之前执行一些清理工作&#xff0c;如释放资源、关闭文件或网络连接等。本文将详细介绍 Python 中的析构函数&#xff0c;包括其定义、语法、调用时机以及实际应用场景。 一、什么是析…

使用QT + 文件IO + 鼠标拖拽事件 + 线程 ,实现大文件的传输

第一题、使用qss&#xff0c;通过线程&#xff0c;使进度条自己动起来 mythread.h #ifndef MYTHREAD_H #define MYTHREAD_H#include <QObject> #include <QThread> #include <QDebug>class mythread : public QThread {Q_OBJECT public:mythread(QObject* …

在 macOS 上使用 CLion 进行 Google Test 单元测试

介绍 Google Test&#xff08;GTest&#xff09;是 Google 开源的 C 单元测试框架&#xff0c;它提供了简单易用的断言、测试夹具&#xff08;Fixtures&#xff09;和测试运行机制&#xff0c;使 C 开发者能够编写高效的单元测试。 本博客将介绍如何在 macOS 上使用 CLion 配…

[MySQL初阶]MySQL(5)内置函数详解

标题&#xff1a;[MySQL初阶]MySQL&#xff08;5&#xff09;内置函数详解 水墨不写bug 文章目录 一、日期函数1. current_date()2. current_time()3. current_timestamp()4. date(datetime)5. date_add(date, interval expr unit)6. date_sub(date, interval expr unit)7. dat…

【MySQL】事务(隔离性、MVCC)

文章目录 1. 事务的概念2. 事务的提交方式3. 事务常见操作4. 隔离性4.1 隔离级别4.2 查看与设置隔离性4.3 隔离级别的测试 5. 隔离性的原理5.1 MVCC5.1.1 3个隐藏字段5.1.2 undo日志5.1.3 模拟MVCC 5.2 Read view5.3 RR与RC的本质区别 1. 事务的概念 在之前所有的SQL操作中&am…

单细胞分析(22)——高效使用 Cell Ranger:安装、参数解析及 Linux 后台运行指南

高效使用 Cell Ranger&#xff1a;安装、参数解析及 Linux 后台运行指南 背景介绍 Cell Ranger 是 10x Genomics 开发的一套用于单细胞转录组测序数据处理的软件。它可以对 10x Genomics 平台生成的 FASTQ 文件进行对齐、UMI 计数和基因表达量计算&#xff0c;是单细胞 RNA-se…

IEEE paper submission

author guideline IEEE 文章模板&#xff1a;https://template-selector.ieee.org/ 1&#xff09;Manuscripts that exceed eight pages will incur mandatory over-length page charges. (超过 8 页强制收费 $175/page) 2&#xff09;Authors are invited to submit manus…

NET431-C协议网关:跨网段·零编程PLC工业通信终极方案

系统框架图解析 三层架构&#xff0c;一图读懂&#xff1a; 设备层&#xff1a; 4个网口2个网段&#xff1a;直连AB、西门子、三菱等18台PLC&#xff0c;覆盖4个网段&#xff08;如10.1.1.0/24、192.168.2.0/24&#xff09;&#xff0c;协议转换。5路RS485串口&#xff1a;通过…

nvm 让 Node.js 版本切换更灵活

有很多小伙伴前端开发进程中&#xff0c;我们常常会遇到不同项目依赖不同版本 Node.js 的情况。我们不可能去卸载重新安装适应的版本去安装依赖或者启动项目。为了避免版本冲突带来的一系列麻烦&#xff0c;在这里给大家推荐一款Node.js 版本管理工具——nvm&#xff08;Node V…

豆包大模型 MarsCode AI 刷题专栏 001

001.找单独的数 难度&#xff1a;易 问题描述 在一个班级中&#xff0c;每位同学都拿到了一张卡片&#xff0c;上面有一个整数。有趣的是&#xff0c;除了一个数字之外&#xff0c;所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上…

迭代器模式:遍历集合的艺术

文章目录 什么是迭代器模式&#xff1f;现实中的例子迭代器模式的结构代码示例1. 定义Iterator接口2. 实现ConcreteIterator3. 定义Aggregate接口4. 实现ConcreteAggregate5. 客户端代码输出结果 迭代器模式的优缺点优点缺点 总结 在软件开发中&#xff0c;我们经常需要遍历集合…

通用文件模型

一、通用文件模型 通常一个完整的Linux系统有数千到数百万个文件组成&#xff0c;文件中存储了程序、数据和各种信息。层次化的目录结构用于对文件进行编排和分组。 1.ReiserFS(新型的文件系统) -->Reiser4 它通过一种与众不同的方式----完全平衡树来容纳数据&#xff0c;包…

DeepSeek + 飞书多维表格搭建你的高效工作流

众所周知&#xff0c;大模型DeepSeek擅长于处理大规模语言模型推理任务&#xff0c;特别是在成本降低和思维链推理方面表现出色‌&#xff0c;我们一般把大模型必做我们的大脑&#xff0c;但是一个人不能只有大脑&#xff0c;还需要其他输入输出以及操作支配的眼耳鼻嘴手足等。…

微服务架构下的 Node.js

Node.js 在微服务架构中的特点 轻量级和高效性 Node.js 以其轻量级和高效的特点&#xff0c;非常适合构建微服务架构。它具有事件驱动和非阻塞 I/O 模型&#xff0c;能够在处理高并发请求时表现出色。这意味着 Node.js 可以同时处理大量的并发连接&#xff0c;而不会因为阻塞…

用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!

下载模型与数据 模型下载&#xff1a; huggingface&#xff1a; Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…

flask-定时任务

文章目录 前言一、APScheduler是什么二、APScheduler 主要功能&#xff1a;三、主要组成部分&#xff1a;四、典型使用场景&#xff1a;五、具体使用1.安装 APScheduler2.假设我们有一个需要五分钟请求一次http接口的任务1.定义一个scheduler.py去专门处理定时2.启动文件处理3.…

Python的Pandas和matplotlib库:让数据可视化贼简单

在数据爆炸的时代&#xff0c;数据可视化已成为数据分析的关键环节。Python 作为强大的编程语言&#xff0c;拥有众多用于数据可视化的库&#xff0c;而 pandas 库在其中扮演着重要角色。它不仅能高效处理和分析数据&#xff0c;还具备强大的数据可视化功能&#xff0c;让我们轻…

rabbitmq版本升级并部署高可用

RabbitMQ版本升级 先检查是否已经安装rabbitmq rpm -qa|grep rabbitmq|wc -l //如果结果是0&#xff0c;表示没有安装 rpm -e --nodeps $(rpm -qa|grep rabbitmq) //如安装了&#xff0c;则进行卸载 先检查是否已经安装erlang rpm -qa|grep erlang|wc -l //如果结果…

Electron-Forge + Vue3 项目初始化

本人对Electron的浅薄理解如下图所示 由上图可以&#xff0c;如果你需要开发一个electron应用&#xff0c;你得具备基本的前端开发经验。对于electron相关的知识&#xff0c;建议先了解下基本的窗口操作&#xff0c;比如新建窗口、关闭窗口等简单的操作&#xff0c;这些内容在…

pinginfoview网络诊断工具中文版

介绍 pinginfoview中文版本是一款实用的网络诊断工具&#xff0c;它专为中文用户设计&#xff0c;提供了方便易用的界面&#xff0c;使得在Windows环境下进行ping测试变得更加简单。该工具是由NirSoft开发的一款免费的桌面应用程序&#xff0c;尽管官方可能并未正式发布中文版…