图片懒加载:从低像素预览到高清加载

老生常谈的问题,图片太多太大的网站,往往由于图片加载过慢而导致页面白屏时间过长。本次年前最后一更,来讲一个加载方法来处理这种情况。

在使用 Next.js 时,发现其支持模糊图片占位符加载的方式,本文就手动实现一个

企业微信截图_0cbf1b0b-91ee-49ff-bb58-a0d390bc61a2.png

图片解释:Nextjs 使用 placeholder=“blur” 来指定当前图片使用模糊图片占位符加载

前置工作

首先你得准备一堆图片,部署一个测试的网页。

<body class="p-12 m-auto">
  <div class="container flex justify-center">
    <img loading="lazy" alt="9" class="w-full object-cover rounded-lg"
      src="http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg">
      ...
      下面是并列的一堆 img,数量 100+

页面预览:

image.png

但是,当网速慢一点,或者图片再高清一点时,图片就会出现加载白屏(从上往下的扫描线)。

设置延迟加载

首先,我们利用 img 标签的能力,添加懒加载属性:

<img loading="lazy" src="image.jpg" alt="..." />

兼容性:

image.png

这个策略有一个动态的原则:

  1. Lazy loading加载数量与屏幕高度有关,高度越小加载数量越少,但并不是线性关系。4G 网络下的视口距离阈值是 1250 像素,3G 网络下是 2500 像素。
  2. Lazy loading加载数量与网速有关,网速越慢,加载数量越多,但并不是线性关系
  3. 滚动会触发图片懒加载,不会说滚动一屏后再去加载。
  4. 窗口resize尺寸变化也会触发图片懒加载。
  5. 根据滚动位置不同,Lazy loading会忽略头尾的图片请求。

这个策略跟浏览器,网速和运行环境都有关系,我就以我本地为准进行测试。为了满足浏览器阈值,我们放置了 100+ 的网络图片,见上面预览图。在初始化加载时只加载了一部分,等往下滚动一些,看效果:

1.gif

注意图片的嵌套层级,如果 html 书写有误,或者嵌套层级过多,懒加载可能不会被触发

配置模糊图片

我们准备好低像素的模糊图片,将每一个 img 用 div 包裹起来,并给 div 加上那个模糊的背景图片(next.js 也是这么做的):

<div class="blur-load" style="background-image: url(模糊图片)">
  <img ... loading="lazy" />
</div>

其中模糊图片的样式可以这样定义, 保证背景图片与 img 能够重合:

img {
  width: 100%;
  aspect-ratio: 1/1;
  object-fit: cover;
  object-position: center;
}

.blur-load {
  background-size: cover;
  background-position: center;
}

这个方法的原理是 img 图片的层级要高于其本身或者父级的背景图片,当图片加载出来后自动覆盖背景图片

制作模糊图片,可以使用 ffmpeg 工具(自行进入官网下载安装即可)。

mac 电脑直接下载 Unix 可执行文件到本地就可以用它执行指令了;windows 电脑直接下载 build 的目录文件,找到 bin 目录下的 ffmpeg.exe 就可以执行了。

运行指令:

# 我做了 20 倍缩放,你可以自己定义缩放比例
ffmpeg -i 1.jpg -vf scale=20:-1 1-sm.png

这样便生成了一个很小的图片:

image.png

调整代码:

<div class="blur-load rounded-lg" style="background-image: url(./1-sm.png)">
<img loading="lazy" alt="9" class="w-full object-cover rounded-lg"
  src="http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg">
</div>

我们将网速调慢看看效果:

image.png

但是这样还有问题,就是图片是从上往下逐渐加载的,部分加载也会显示的页面上:

1.gif

我们想要的效果是图片完全加载后再让图片出来,这要借助 js:

function loaded(div) {
  div.classList.add('loaded');
}

const blurDivs = document.querySelectorAll('.blur-load');
blurDivs.forEach(div => {
  const img = div.querySelector('img');
  
  // 在加载完成的时候添加样式
  if (img.complete) { loaded(div) }
  else { img.addEventListener('load', () => loaded(div)) }
})

这样,在加载完成后才会有 ‘loaded’ 样式加载在外围的 div 上。我们只需要给 div 添加样式:

.blur-load.loaded > img {
 opacity: 1;
}

/* 加载完成之前保持透明 */
.blur-load > img {
  opacity: 0;
  transition: opacity 200ms ease-in-out;
}

这样在加载完成后才会有模糊图片过渡显示为原图的效果了:

1.gif

自定义 loading 动画

如果你自己觉得还不满意,想要自己加入想要的动画效果,那么你可以子在这个div上自己定义样式。下面给出一种脉冲效果的参考样例:

.blur-load {
  position: relative;
}
.blur-load::before {
  content: "";
  position: absolute;
  inset: 0;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    background-color: rgba(255, 255, 255, 0);
  }
  
  50% {
    background-color: rgba(255, 255, 255, 0.4);
  }
  
  100% {
    background-color: rgba(255, 255, 255, 0);
  }
}

/* 加载完成后取消 */
.blur-load.loaded::before {
  content: none;
}

效果图如下:

1.gif

最后

欢迎关注"所谓前端"微信公众号,大家一起交流
点击扫码关注

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

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

相关文章

最近vscode链接Autodl出现的问题

最近vscode链接Autodl出现的问题 一、问题的概述 在使用vscode连接autodl远程服务器的时候&#xff0c;在vscode的右下角出现了&#xff0c;以下的问题提示&#xff1a; 远程主机可能不符合glibc和libstdc VS Code服务器的先决条件 二、问题的原因 vscode版本过高的问题&…

远程git仓库已有仓库,若想本地代码覆盖远程代码,操作如下

1.首先 2.其次 3.然后 4.最后 git push -f origin "master" -f&#xff1a;强制推送&#xff0c;若远程是空项目&#xff0c;可以换成-u

基于Java (spring-boot)的宿舍管理系统

一、项目介绍 基于Java (spring-boot)的宿舍管理系统功能&#xff1a;登录界面、宿舍管理、学生管理、班级管理、宿舍楼管理、维修记录、晚归记录、请假记录、用户管理、角色管理、菜单管理、日志管理、我收到的、退宿审核&#xff0c;等等等 二、作品包含 三、项目技术 后端语…

MATLAB环境下生成对抗网络系列(11种)

为了构建有效的图像深度学习模型&#xff0c;数据增强是一个非常行之有效的方法。图像的数据增强是一套使用有限数据来提高训练数据集质量和规模的数据空间解决方案。广义的图像数据增强算法包括&#xff1a;几何变换、颜色空间增强、核滤波器、混合图像、随机擦除、特征空间增…

人生就是一场大考

感觉人生就是一场大考&#xff0c;最重要的高考&#xff0c;而这个考试要到49岁左右才有得分。如&#xff0c;当初事业的选择&#xff0c;爱情伴侣的选择&#xff0c;出去在外发展的选择……这都决定了你以后人生高考的走向。现在的你过得怎么样&#xff0c;也是你在人生这场高…

Java实现河南软件客服系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、系统展示四、核心代码4.1 查询客户4.2 新增客户跟进情况4.3 查询客户历史4.4 新增服务派单4.5 新增客户服务费 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的河…

机器学习系列5-特征组合、简化正则化

1.特征组合 1.1特征组合&#xff1a;编码非线性规律 我们做出如下假设&#xff1a;蓝点代表生病的树。橙色的点代表健康的树。 您可以绘制一条直线将生病的树与健康的树清晰地分开吗&#xff1f;不可以。这是一个非线性问题。您绘制的任何线条都无法很好地预测树的健康状况…

1【算法】——最大子数组问题(maximum subarray)

一.问题描述 假如我们有一个数组&#xff0c;数组中的元素有正数和负数&#xff0c;如何在数组中找到一段连续的子数组&#xff0c;使得子数组各个元素之和最大。 二.问题分析 分治法求解&#xff1a; 初始状态&#xff1a; low0&#xff1b;highA.length-1&#xff1b;mid&am…

GO 的 Web 开发系列(五)—— 使用 Swagger 生成一份好看的接口文档

经过前面的文章&#xff0c;已经完成了 Web 系统基础功能的搭建&#xff0c;也实现了 API 接口、HTML 模板渲染等功能。接下来要做的就是使用 Swagger 工具&#xff0c;为这些 Api 接口生成一份好看的接口文档。 一、写注释 注释是 Swagger 的灵魂&#xff0c;Swagger 是通过…

leaflet 显示自己geoserver发布的中国地图

安装vscode 安装 通义灵码 问题&#xff1a; 用leaflet显示一个wms地图 修改下代码&#xff0c;结果如下&#xff1a; 例子代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&q…

【HarmonyOS 4.0 应用开发实战】ArkTS 快速入门之常用属性

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

《统计学简易速速上手小册》第5章:回归分析(2024 最新版)

文章目录 5.1 线性回归基础5.1.1 基础知识5.1.2 主要案例&#xff1a;员工薪资预测5.1.3 拓展案例 1&#xff1a;广告支出与销售额关系5.1.4 拓展案例 2&#xff1a;房价与多个因素的关系 5.2 多元回归分析5.2.1 基础知识5.2.2 主要案例&#xff1a;企业收益与多因素关系分析5.…

【小沐学GIS】基于WebGL绘制三维数字地球Earth(OpenGL)

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐学GIS】…

最短路径算法

1. Dijkstra算法 在正数权重的有向图中求解某个源点到其余各个顶点的最短路径一般可以采用迪杰斯特拉算法&#xff08;Dijkstra算法&#xff09;。 1.1 适用场景 单源最短路径权重都为正 1.2 伪代码 1.3 示例 问题描述&#xff1a; 计算节点0到节点4的最短路径&#xff0c…

arduino uno R3驱动直流减速电机(蓝牙控制)

此篇博客用于记录使用arduino驱动直流减速电机的过程&#xff0c;仅实现简单的功能&#xff1a;PID调速、蓝牙控制 1、直流减速电机简介2、DRV8833电机驱动模块简介3、HC-05蓝牙模块简介电机转动测试4、PID控制5、蓝牙控制电机 1、直流减速电机简介 我在淘宝购买的电机&#x…

C语言整型数据类型..

1.整型数据类型 在C语言中 根据数据范围从小到大依次为char、short、int、long、long long 但是对于整型来说 为什么有这么多类型呢 我们得先说字节的本质&#xff1a; 计算机是通过晶体管的开关状态来记录数据 晶体管通常8个为一组 称为一个字节 而晶体管由两种状态 分别是开…

交叉熵损失函数(Cross-Entropy Loss)的基本概念与程序代码

交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;是机器学习和深度学习中常用的损失函数之一&#xff0c;用于分类问题。其基本概念如下&#xff1a; 1. 基本解释&#xff1a; 交叉熵损失函数衡量了模型预测的概率分布与真实概率分布之间的差异。在分类问题中&…

春节假期:思考新一年的发展思路

春节假期是人们放松身心、享受家庭团聚的时刻&#xff0c;但除了走亲戚、玩、吃之外&#xff0c;我们确实也需要思考新的一年的发展思路。以下是一些建议&#xff0c;帮助您在春节假期中为新的一年做好准备&#xff1a; 回顾过去&#xff0c;总结经验&#xff1a;在春节期间&a…

大华智慧园区综合管理平台/emap/devicePoint RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【十六】【C++】stack的常见用法和练习

stack的常见用法 C标准库中的stack是一种容器适配器&#xff0c;它提供了后进先出&#xff08;Last In First Out, LIFO&#xff09;的数据结构。stack使用一个底层容器进行封装&#xff0c;如deque、vector或list&#xff0c;但只允许从一端&#xff08;顶部&#xff09;进行…