原文地址:https://www.sitepoint.com/fiv…
原文作者:Maria Antonietta Perna
因为图像是 Web 上最重要的内容之一,因而网站上的页面加载工夫很容易成为问题。
即便进行了适当的优化,图像也可能会很重。这会对访问者必须期待能力拜访您网站上的内容的工夫产生负面影响。除非您想出一种不会影响速度感知的图像加载解决方案,否则来到你的网站。
在本文中,您将理解五种提早加载图像的办法,能够将其增加到网络优化工具包中以改善网站上的用户体验。
1. 什么是提早加载(懒加载)
提早加载图片是指异步加载网站上的图片,也就是说,在首屏内容齐全加载后,如果用户不向下滚动,放在页面底部的图片甚至不会被加载。
很多网站都应用这种办法,但在图片较多的网站上尤为显著。浏览您最喜爱的壁纸网站以获取高分辨率壁纸时,你很快就会意识到网站只能加载无限数量的图片。当您向下滚动页面时,您将看到占位符图像疾速地被实在图像填充以进行预览。
2. 为什么要关怀提早加载图像?
这里有两个极其重要的因素,让您思考为网站提早加载图像:
- 如果您的网站应用 JavaScript 来显示内容或向用户提供某种性能,则疾速加载 DOM 变得至关重要。脚本通常要等到 DOM 齐全加载后能力开始运行。在蕴含大量图像的网站上,提早加载(或异步加载图像)可能会导致用户停留或来到您的网站有所不同。
- 因为大多数提早加载解决方案仅在用户滚动到在视口内可见图像的地位时才加载图像,因而如果用户从未达到该点,则将永远不会加载这些图像。这意味着能够节俭大量带宽,为此,大多数用户,特地是那些在挪动设施上拜访 Web 且连贯迟缓的用户,用户体验将十分的好。
好吧,提早加载图片有助于进步网站性能,然而最好的解决办法是什么?
没有完满的方法。
如果您相熟 JavaScript,那么实现本人的提早加载解决方案就不会成为问题。没有什么比本人编写代码更能给你控制权了。
或者,您能够浏览 Web 以找到可行的办法并开始进行试验。我就是这样做的,并遇到了这五种乏味的技术。
2.1 Native Lazy Loading
本地提早加载图像和 iframes
是十分酷的。没有什么比上面的代码更间接的了
<img src="myimage.jpg" loading="lazy" alt="..." />
<iframe src="content.html" loading="lazy"></iframe>
如您所见,没有 JavaScript
,也没有动静替换src
属性的值,只是一般的HTML
。
loading
属性使咱们能够抉择提早屏幕外图像和iframe
,直到用户滚动到页面上的地位为止。加载能够采纳以下三个值之一:
lazy
:提早加载eager
:浏览器立刻加载指定的内容auto
:将选项保留为提早加载或不提早加载至浏览器。
这种办法无可匹敌:开销为零,简洁明了。然而,只管在撰写本文时,大多数支流浏览器都对 loading
属性提供了很好的反对,但并不是所有浏览器都反对。
2.2 IntersectionObserver API
Intersection Observer API 是一个现代化的接口,您能够利用它来提早加载图像和其余内容。
MDN 引入此 API 的办法如下:
Intersection Observer API 提供了一种异步察看指标元素与先人元素或顶级文档视口相交的变动的办法。
换句话说,被异步监督的是一个元素与另一个元素的交加。
Denys Mishunov 在 IntersectionObserver
和应用它的提早加载图像方面都有很好的教程。这是他的解决方案。
假如您要提早加载图片库。每个图像的标记如下所示:
<img data-src="image.jpg" alt="test image">
请留神,图像的门路是如何蕴含在 data-src
属性而不是 src
属性中的。起因是应用 src
意味着图像将立刻加载,这不是您想要的。
在 CSS 中,为每个图像指定一个最小高度值,例如 100px
。这为每个图像占位符(不带src
属性的 <img>
元素)提供了一个垂直尺寸:
img {
min-height: 100px;
/* more styles here */
}
而后,在 JavaScript
文档中,创立一个配置对象,并向一个 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
preloadImage(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
在计算方面可能承当沉重的工作。
另一方面,尽管大多数浏览器都反对IntersectionObserver
API 的最新版本,但并非所有浏览器都始终反对该 API。侥幸的是,能够应用polyfill
。
2.3 Lozad.js
实现图像的提早加载的一种疾速简便的代替办法是让 JS
库为您实现大部分工作。
Lozad.js 是纯 JavaScript
中的高性能,轻量且可配置的惰性加载器,没有任何依赖关系。您能够应用它来提早加载图像,视频,iframe
和更多内容,并且它应用IntersectionObserver API
。
您能够将 Lozad.js 蕴含在 npm / Yarn
中,并应用模块化将其导入:
npm install --save lozad
yarn add lozad
import lozad from 'lozad';
另外,您能够简略地应用 CDN 下载该库并将其增加到 <script>
标记中的 HTML 页面底部:
<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
接下来,对于根本实现,将 lozad
类增加到 html
标签上:
<img class="lozad" data-src="img.jpg">
最初,在您的 JS 文档中实例化 Lozad:
const observer = lozad();
observer.observe();
您将在 Lozad GitHub 存储库中找到无关如何应用该库的所有详细信息。
如果您不想深刻理解 IntersectionObserver API
的工作原理,或者只是在寻找实用于各种内容类型的疾速实现,则 Lozad.js 是一个不错的抉择。
仅留神浏览器反对,并最终将此库与用于 Intersection Observer API
的 polyfill 集成。
2.4 提早加载具备含糊的图像成果
如果您是认真的读者,那么您必定曾经留神到该网站如何在帖子中加载主图像。
你首先看到的是一个含糊的、低分辨率的图像正本,而它的高分辨率版本正在被提早加载
高分辨率,懈怠加载图像在媒体网站
您能够通过多种形式来提早加载具备这种乏味的含糊成果的图像。
我最喜爱的技术是 Craig Buckler。这是此解决方案的全副长处:
- 性能:仅 463B 的 CSS 和 1,007B 的 JavaScript 代码
- 对视网膜屏幕的反对
- 无依赖性: 不须要 jQuery 或其余库和框架
- 逐渐加强性能以对消较旧的浏览器和 JavaScript 失败
2.5 Yall.js
Yall 是功能丰富的提早加载脚本,用于图像,视频和iframe
。更具体地说,它应用 Intersection Observer API 并在必要时奇妙地应用传统的事件处理程序技术。
在文档中蕴含 Yall 时,须要按以下形式对其进行初始化:
<script src="yall.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", yall);
</script>
接下来,要提早加载一个简略的 img
元素,您在标记中须要做的就是:
<img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image.">
留神:
- 将
class="lazy"
增加到元素 src
的值是一个占位符图像- 您要提早加载的图像的门路放到在
data-src
属性内
Yall 的益处包含:
- Intersection Observer API 的杰出性能
- 杰出的浏览器反对(可回溯到 IE11)
- 不须要其余依赖项
3、论断
这样就能够了–提早加载图像的五种办法,您能够开始在我的项目中进行试验和测试。