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

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

在使用 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

最后

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft OneNote 图片文字提取

Microsoft OneNote 图片文字提取 1. 文件 -> 新建 -> 我的电脑 -> 名称 -> 位置 -> 创建笔记本2. 插入图片​​​3. 复制图片中的文本References 1. 文件 -> 新建 -> 我的电脑 -> 名称 -> 位置 -> 创建笔记本 ​ 2. 插入图片 ​​​3. 复制图片…

监测Nginx访问日志502情况后并做相应动作

今天带大家写一个比较实用的脚本哈 原理&#xff1a; 假设服务器环境为lnmp&#xff0c;近期访问经常出现502现象&#xff0c;且502错误在重启php-fpm服务后消失&#xff0c;因此需要编写监控脚本&#xff0c;一旦出现502&#xff0c;则自动重启php-fpm服务 场景&#xff1a; 1…

基于VUE框架的旅游平台82070-计算机毕业设计项目选题推荐(免费领源码)

摘 要 改革开放以来&#xff0c;我国的旅游业有了非常迅速的发展&#xff0c;但是比较而言&#xff0c;我国国内旅游业发展的广度深度都远远不能适应经济发展和人民生活水平提高的需要。随着市场经济的发展和人民收入水平的进一步提高&#xff0c;人民对旅游消费的需求将进一步…

java nio零拷贝

零拷贝是一种计算机执行IO操作的优化技术&#xff0c;其核心目标是减少数据拷贝次数&#xff0c;从而提高系统性能。它主要体现在以下几个方面&#xff1a; 1. **定义与原理**&#xff1a;零拷贝字面上的意思包括“零”和“拷贝”。其中&#xff0c;“拷贝”是指数据从一个存储…

鸿蒙开发理论之页面和自定义组件生命周期

1、自定义组件和页面的关系 页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定义组件为页面的入口组件&#xff0c;即页面的根节点&#xff0c;一个页面有且仅能有一个Entry。只有被Entry装饰的组件才可以调用页面的生命周期。自…

(三十五)大数据实战——Superset可视化平台搭建

前言 本节内容是关于Apache Superset可视化平台的搭建&#xff0c;Apache Superset是一个现代的数据探索和可视化平台 。它功能强大且十分易用&#xff0c;可对接各种数据源&#xff0c;包括很多现代的大数据分析引擎&#xff0c;拥有丰富的图表展示形式&#xff0c;并且支持自…

最简单的基于 FFmpeg 的视频编码器(YUV 编码为 H.264)

最简单的基于 FFmpeg 的视频编码器&#xff08;YUV 编码为 H.264&#xff09; 最简单的基于 FFmpeg 的视频编码器&#xff08;YUV 编码为 H.264&#xff09;正文结果工程文件下载 最简单的基于 FFmpeg 的视频编码器&#xff08;YUV 编码为 H.264&#xff09; 参考雷霄骅博士的…

阿里云服务器“带宽计费模式”怎么选?有啥区别?

阿里云服务器带宽计费模式分为“按固定带宽”和“按使用流量”&#xff0c;有什么区别&#xff1f;按固定带宽是指直接购买多少M带宽&#xff0c;比如1M、5M、10M、100M等&#xff0c;阿里云直接分配用户所购买的带宽值&#xff0c;根据带宽大小先付费再使用&#xff1b;按使用…

Linux第50步_移植ST公司的linux内核第2步_编译ST公司的linux源码和修改网络驱动

1、修改“linux-5.4.31”目录下的“Makefile” 1)、使用VSCode打开“linux-5.4.31.code-workspace” 2)、点击“linux-5.4.31”目录下的“Makefile” 3)、点击“编辑”&#xff0c;点击“查找”&#xff0c;输入“CROSS_COMPILE回车”&#xff0c;找到“ARCH ? $(SUBARCH)”…

第77讲用户管理功能实现

用户管理功能实现 前端&#xff1a; views/user/index.vue <template><el-card><el-row :gutter"20" class"header"><el-col :span"7"><el-input placeholder"请输入用户昵称..." clearable v-model"…

HAproxy+Mycat集群+MySQL主从组成高可用性方案架构图

如果还担心 HAproxy 的稳定性和单点问题&#xff0c;则可以用 keepalived 的 VIP 的浮动功能&#xff0c;加以强化&#xff1a;https://blog.csdn.net/gaofenglxx/article/details/118883060

Linux diff命令

参考资料 【 diff 】コマンド&#xff08;基本編&#xff09;――テキストファイルの差分を出力する便利なdiffコマンド使い方 目录 前期准备一. 基本语法二. 文件比较2.1 无配置项2.2 -B 忽略空行&#xff0c;-w忽略空格2.3 -y 文件内容横向比较显示2.4 -q 仅显示文件是否不同…