五种延迟加载图像以提高网站性能的方法

由于图像是网络上最受欢迎的内容类型之一,网站上的页面加载时间很容易成为一个问题。

即使经过适当优化,图像的重量也会相当大。这可能会对访问者在访问您网站上的内容之前必须等待的时间产生负面影响。很有可能,他们会变得不耐烦并在其他地方导航,除非您想出一个不影响速度感知的图像加载解决方案。

在本文中,您将了解五种延迟加载图像的方法,您可以将这些方法添加到您的Web优化工具包中,以改善您网站上的用户体验。

什么是延迟加载?

延迟加载图片意味着在网站上异步加载图片——也就是说,在首屏内容完全加载之后,或者甚至有条件地,只有当它们出现在浏览器的视口中时。这意味着如果用户不一直向下滚动,放置在页面底部的图像甚至不会被加载。

许多网站都使用这种方法,但在图片较多的网站上尤为明显。尝试浏览您最喜欢的在线猎场以获取高分辨率照片,您很快就会意识到该网站如何只加载有限数量的图像。当您向下滚动页面时,您会看到占位符图像快速填充真实图像以供预览。例如,注意Unsplash.com上的加载器:将页面的该部分滚动到视图中会触发用全分辨率照片替换占位符:

为什么要关心延迟加载图像?

您应该考虑为您的网站延迟加载图像至少有几个很好的理由:

如果您的网站使用JavaScript来显示内容或向用户提供某种功能,那么快速加载 DOM 就变得至关重要。脚本通常要等到 DOM 完全加载后才开始运行。在拥有大量图像的网站上,延迟加载(或异步加载图像)可能会影响用户停留或离开您的网站。

由于大多数延迟加载解决方案仅在用户滚动到图像在视口内可见的位置时才加载图像,因此如果用户从未到达该点,则永远不会加载这些图像。这意味着带宽的大量节省,大多数用户,尤其是那些使用移动设备和慢速连接访问Web的用户,都会感谢您。

好吧,延迟加载图像有助于提高网站性能,但最好的方法是什么?

没有完美的方法。

如果您熟悉JavaScript,那么实现您自己的延迟加载解决方案应该不是问题。没有什么比自己编写代码更能控制你的了。

或者,您可以浏览Web以寻找可行的方法并开始试验它们。我就是这样做的,并遇到了这五种有趣的技术。

#1 原生延迟加载

图像和iframe的原生延迟加载非常酷。没有什么比下面的标记更直接了:

如您所见,没有 JavaScript,没有动态交换src属性值,只是普通的旧 HTML。

该loading属性为我们提供了延迟屏幕外图像和iframe的选项,直到用户滚动到他们在页面上的位置。loading可以采用以下三个值中的任何一个:

lazy: 非常适合延迟加载

eager: 指示浏览器立即加载指定的内容

auto:保留延迟加载或不延迟加载到浏览器的选项。

这种方法没有竞争对手:它的开销为零,干净简单。然而,尽管在撰写本文时,大多数主要浏览器都对loading属性有很好的支持,但并非所有浏览器都支持。

有关延迟加载图像的这项出色功能(包括浏览器支持变通方法)的深入文章,请不要错过 Addy Osmani 的“网络原生图像延迟加载”!。

#2 使用 Intersection Observer API 延迟加载

Intersection Observer API 是一个现代化的界面,你可以利用的延迟加载图片和其他内容。Intersection Observer API 提供了一种异步观察目标元素与祖先元素或顶级文档视口的交集变化的方法。

换句话说,被异步观察的是一个元素与另一个元素的交集。

Denys Mishunov 有一个关于 Intersection Observer 和使用它的延迟加载图像的很棒的教程。这是他的解决方案的样子。



假设您想延迟加载图片库。每个图像的标记如下所示:

请注意图像的路径如何包含在data-src属性中,而不是src属性中。原因是使用src意味着图像会立即加载,这不是您想要的。

在 CSS 中,您为每个图像赋予一个min-height值,例如100px. 这为每个图像占位符(没有 src 属性的 img 元素)提供了一个垂直维度:

img { min-height: 100px; /* more styles here */ }

然后在JavaScript文档中创建一个config对象并将其注册到一个intersectionObserver实例中:// create config object: rootMargin and threshold // are two properties exposed by the interface const config = { rootMargin: '0px 0px 50px 0px', threshold: 0 }; // register the config object with an instance // of intersectionObserver let observer = new intersectionObserver(function(entries, self) { // iterate over each entry entries.forEach(entry = { // process just the images that are intersecting. // isIntersecting is a property exposed by the interface if(entry.isIntersecting) { // custom function that copies the path to the img // from data-src to src ploadImage(entry.target); // the image is now in place, stop watching self.unobserve(entry.target); } }); }, config);>最后,您遍历所有图像并将它们添加到此iterationObserver实例中:

const imgs = document.querySelectorAll('[data-src]'); imgs.forEach(img = { observer.observe(img); });该解决方案的优点:实施起来轻而易举,有效,并且可以在intersectionObserver计算方面进行繁重的工作。

另一方面,尽管最新版本的大多数浏览器都支持 Intersection Observer API,但并非所有浏览器都一致支持。幸运的是,有一个polyfill可用。>#3 Lozad.js

实现图像延迟加载的一种快速简便的替代方法是让 JS 库为您完成大部分工作。

Lozad 是一个高性能、轻量级和可配置的纯JavaScript惰性加载器,没有依赖项。您可以使用它来延迟加载图像、视频、iframe 等,并且它使用 Intersection Observer API。

你可以在 npm/Yarn 中包含 Lozad 并使用你选择的模块打包器导入它:

npm install --save lozad yarn add lozad

import lozad from 'lozad';

或者,您可以简单地使用 CDN 下载库并将其添加到 HTML 页面底部的

标签中:

接下来,对于基本实现,将类lozad添加到标记中的资产:

最后,在你的 JS 文档中实例化 Lozad:< script>const observer = lozad(); observer.observe();

您将在Lozad GitHub 存储库上找到有关如何使用该库的所有详细信息。



如果您不想深入研究 Intersection Observer API 的工作原理,或者您只是在寻找适用于各种内容类型的快速实现,那么 Lozad 是一个不错的选择。

只是,请注意浏览器支持,并最终将此库与 Intersection Observer API 的 polyfill 集成。

#4 图像模糊效果的延迟加载

如果您是Medium读者,您肯定已经注意到该网站如何在帖子中加载主图片。

您首先看到的是图像的模糊、低分辨率副本,而其高分辨率版本正在延迟加载。

您可以通过多种方式延迟加载具有这种有趣模糊效果的图像。

我们最喜欢的技术是 Craig Buckler。这是此解决方案的所有优点:

性能:只有 463 字节的 CSS 和 1,007 字节的缩小JavaScript代码

支持视网膜屏幕

无依赖:不需要 jQuery 或其他库和框架

逐步增强以抵消旧浏览器和失败的 JavaScript

#5 Yall.js

Yall 是一个功能丰富的延迟加载脚本,用于图像、视频和 iframe。更具体地说,它使用 Intersection Observer API,并在必要时巧妙地使用传统的事件处理程序技术。

在您的文档中包含 Yall 时,您需要按如下方式对其进行初始化:



接下来,要延迟加载一个简单的img元素,您只需在标记中执行以下操作:

请注意以下事项:

您将类添加到元素

src值是一个占位符图像



要延迟加载的图像的路径在data-src属性内

Yall 的好处包括:

Intersection Observer API 的出色性能

出色的浏览器支持(它可以追溯到 IE11)

不需要其他依赖项

结论

你有五种延迟加载图像的方法,您可以开始在您的项目中进行试验和测试。


分享文章:五种延迟加载图像以提高网站性能的方法
网页地址:http://pwwzsj.com/article/sjddio.html