懒加载图片以获取最佳性能的最佳方案

简介: 图片懒加载是一个很受欢迎的优化站点的方法,因为它很容易实现,并且能明显提升性能。使用惰性加载,我们可以异步加载图片,这意味着可以只加载浏览器视口内的图片。大约一年前,图像和iframe的原生惰性加载特性已发布,但是仅针对谷歌和其他主流浏览器。该功能的重点是使浏览器可以控制何时请求图像或iframe资源,这使得开发工作更加容易。在此前,唯一的选择是使用JavaScript插件来监视视口更改并动态加载资源。现在,浏览器也可以原生支持(懒加载)。

图片懒加载是一个很受欢迎的优化站点的方法,因为它很容易实现,并且能明显提升性能。使用惰性加载,我们可以异步加载图片,这意味着可以只加载浏览器视口内的图片。 大约一年前,图像和iframe的原生惰性加载特性已发布,但是仅针对谷歌和其他主流浏览器。该功能的重点是使浏览器可以控制何时请求图像或iframe资源,这使得开发工作更加容易。在此前,唯一的选择是使用JavaScript插件来监视视口更改并动态加载资源。现在,浏览器也可以原生支持(懒加载)。


在写此文时候(原文在dev.to上是2020年8月31日发布),大约73% of currently used browsers支持这个特性,这还不赖。但是,我们不想让27%的潜在用户无法访问和使用网站的图片资源。


所以,这就很有趣了,值得思考:


  • 对于支持原生懒加载特性的浏览器,我们想直接使用它
  • 对于不支持原生懒加载特性的浏览器,我们使用JS插件
  • 根据浏览器对原生懒加载特性支持与否,考虑是否引入JS插件
  • 必须同时支持imgsource元素


loading 属性


loading属性有三个值。


  • auto - 默认值。和不设置loading属性效果一样。
  • eager - 立即加载资源。
  • lazy - 一旦资源在视口就加载它


尽管上面的取值有特定的使用案例,但是,我们通常希望对折叠以上(视口)的资源使用eager,对折叠以下的资源使用lazy


现代的方法


我们需要编写一个脚本,该脚本将在HTML文档后运行。我们使用了Jekyll,并将脚本作为HTML的部分添加在body的末尾。这是运行JavaScript函数以避免渲染阻塞的最有效方法。


标记图片


我们希望JavaScript函数基于浏览器原生支持的特性来开启图像加载过程。为此,我们将图像的路径添加到data-src而不是src。但是我们不应该将src留空,因此我们将使用1 x 1px透明图像占位符。我们对img元素标记如下所示:


<img 
  src="/path/to/placeholder/image.png"
  data-src="/path/to/full/image.jpg"
  alt="Image description"
  class="lazyload"
  loading="lazy"
/>
复制代码


⚠️ class="lazyload"是给懒加载后备插件使用的。我使用了此特定类名的插件lazysizes


另外,我们想支持picture元素,它包含多个source元素并且img元素作为后备元素。


<picture>
  <source data-srcset="path/to/image.webp" type="image/webp" />
  <source data-srcset="path/to/image.jpg" />
  <img loading="lazy" 
    class="lazyload"
    src="path/to/placeholder/image.png"
    data-src="path/to/image.jpg"
    alt="Image description"
  />
</picture>
复制代码


特性检测


我们需要检测用户的浏览器是否支持原生的懒加载。幸运的是,我们可以直接使用JavaScript去做这件事。


if ("loading" in HTMLImageElement.prototype) {
  /* Native lazy loading is supported */
 } else {
  /*  Native lazy loading is not supported */
 }
复制代码


最终JavaScript代码


对于原生懒加载,我们只需要对img分配data-src值给src值,对source分配data-srcset值给srcset值,剩下的事情就交给浏览器了。


对于不支持该特性的浏览器,我们只需要加载相关的JavaScript插件,可选的,如果没有自动化集成的,那么就运行该插件。

我习惯使用lazysizes,但是任何懒加载插件都会生效,前提是保证元素的标记要正确(比如类名,data元素等)。


于是,最终的JavaScript的代码会看起来长这样:


<script>
  if ("loading" in HTMLImageElement.prototype) {
    var images = document.querySelectorAll('img[loading="lazy"]');
    var sources = document.querySelectorAll("source[data-srcset]");
    sources.forEach(function (source) {
      source.srcset = source.dataset.srcset;
    });
    images.forEach(function (img) {
      img.src = img.dataset.src;
    });
  } else {
    var script = document.createElement("script");
    script.src = "/link/to/lazyload.js";
    document.body.appendChild(script);
  }
</script>
复制代码


本文截取Best way to lazy load images for maximum performance部分翻译,进行学习和总结。懒加载在商城站点和运营活动的场景使用更加频繁,当然,图片还要进行最优压缩、切割和CDN处理等。


相关文章
|
API
vue3.0 router路由跳转传参(router.push)
vue3.0 router路由跳转传参(router.push)
1335 0
|
11月前
|
SQL 分布式计算 大数据
湖仓融合:MaxComputee与Hologres基于OpenLake的湖上解决方案
本次主题探讨湖仓融合:MaxCompute与Hologres基于OpenLake的湖上解决方案。首先从数据湖和数据仓库的历史及业界解决方案出发,分析湖仓融合的两种思路;接着针对国内问题,介绍阿里云如何通过MaxCompute和Hologres解决湖仓融合中的挑战,特别是在非结构化数据处理方面的能力。最后,重点讲解Object Table为湖仓增添了SQL生态的非结构化数据处理能力,提升数据处理效率和安全性,使用户能够在云端灵活处理各类数据。
|
机器学习/深度学习 计算机视觉 异构计算
【YOLOv8改进 - Backbone主干】FasterNet:基于PConv(部分卷积)的神经网络,提升精度与速度,降低参数量。
【YOLOv8改进 - Backbone主干】FasterNet:基于PConv(部分卷积)的神经网络,提升精度与速度,降低参数量。
|
存储 传感器 编解码
STM32外设系列—BH1750
本文详细介绍了BH1750的特点,原理图,IIC通信协议。给出了BH1750程序设计,能够实时获取周围环境光照强度。最后,给出了两种拓展应用,并说明了实现思路。
2115 0
STM32外设系列—BH1750
|
JSON 前端开发 数据格式
关于JWT令牌和过滤器以及拦截器的实现流程
JWT令牌用于验证用户请求合法性,登录时通过Filter或Interceptor校验账号密码,生成JWT并返回给前端保存。请求时,后端通过解析令牌检查其完整性、时效性和合法性。Filter在请求处理前检查是否携带JWT,Interceptor的preHandle方法同样用于此目的。两者选择其一即可,拦截器配置更精确但稍复杂。
|
人工智能 决策智能
【AI Agent系列】【MetaGPT多智能体学习】3. 开发一个简单的多智能体系统,兼看MetaGPT多智能体运行机制
【AI Agent系列】【MetaGPT多智能体学习】3. 开发一个简单的多智能体系统,兼看MetaGPT多智能体运行机制
546 0
|
移动开发 前端开发 JavaScript
使用JavaScript实现一个复杂功能:自定义拖拽排序列表
使用JavaScript实现一个复杂功能:自定义拖拽排序列表
|
监控 网络协议 Linux
游戏有延迟?如何获得一个好的Ping
游戏有延迟?如何获得一个好的Ping
|
前端开发 容器 JavaScript
|
网络架构
计算机网络实验(思科模拟器Cisco Packet Tracer)——路由器配置
计算机网络实验(思科模拟器Cisco Packet Tracer)——路由器配置
计算机网络实验(思科模拟器Cisco Packet Tracer)——路由器配置