有几种不同的“传统”图片延迟加载方法。它们都需要 JavaScript 来判断图片是否当前在浏览器的视窗内。传统的做法可能是
- 监听
window
上的scroll
和resize
事件 - 使用
setInterval
等定时器
这些方法都有性能问题。
如果您现在想在网站的媒体上添加延迟加载功能,Lozad.js 不失为一个不错的选择,但原生支持即将推出,因此您应该在标记计划中考虑这一点。
为什么传统做法效率不高?
上面列出的两种方法都存在问题,因为它们会反复工作,并且它们的函数会在计算元素相对于视窗的位置(以检查元素是否在视窗内)时触发强制布局。
为了解决这些性能问题,一些库会限制执行这些操作的函数调用,限制其执行次数。
即使这样,反复触发布局/重绘操作也会在用户与网站交互时消耗宝贵的时间,并导致“垃圾”(用户不喜欢网站交互时的迟钝感)。
我们可以使用另一种方法,它利用了一个新的浏览器 API,该 API 专为帮助我们处理延迟加载等任务而设计:Intersection Observer API。
这正是我自己的库 Lozad.js 使用的方法。

是什么让 Lozad.js 如此高效?
Intersection Observers 是主要成分。它们允许注册回调函数,当监视的元素进入或退出另一个元素(或视窗本身)时,这些函数会被调用。
虽然 Intersection Observers 不会提供精确的重叠像素,但它们允许监听事件,这些事件允许我们观察元素是否以 X%(可配置)进入其他元素,然后回调函数会被触发。当使用 Intersection Observers 进行延迟加载时,这正是我们的用例。
关于 Lozad.js 的快速事实
- 轻量级:仅 535 字节,已压缩和 gzip
- 无依赖项
- 使用 IntersectionObserver API
- 允许对动态添加的元素(不仅仅是图片)进行延迟加载,尽管需要自定义加载函数
用法
从 npm
安装
yarn add lozad
或通过 CDN
<script src="https://cdn.jsdelivr.net.cn/npm/lozad"></script>
在您的 HTML 中,为要延迟加载的任何图片添加一个类。该类可以通过配置更改,但默认值为“lozad”。
<img class="lozad" data-src="image.png">
还要注意,我们已删除图片的 src
属性,并将其替换为 data-src
。这样可以防止图片在 JavaScript 执行并确定应该加载图片之前被加载。最终是否使用此方法取决于您,请考虑其带来的影响。使用此 HTML,图片在 JavaScript 执行之前将不会显示。它们在 RSS 或其他聚合中也不会显示。您可能希望过滤您的 HTML,仅当在您自己的网站上显示时才使用此标记模式,而不是其他地方。
在 JavaScript 中,使用选项初始化 Lozad 库
const observer = lozad(); // lazy loads elements with default selector as ".lozad"
observer.observe();
阅读 此处,了解 Lozad.js API 中提供的所有选项的完整列表。
演示
查看 Apoorv Saxena (@ApoorvSaxena) 在 CodePen 上的 Pen oGgxJr。
浏览器支持
浏览器支持有限,因为此功能相对较新。使用 官方 IntersectionObserver 填充程序 来克服此 API 的有限支持。
“浏览器支持有限,因为此功能相对较新。使用官方 IntersectionObserver 填充程序来克服此 API 的有限支持。”
这意味着我们必须自己实现它,还是 lozad 会自动执行?
听起来我们必须自己动手,但如果浏览器支持有限,我认为许多人会想要它。也许您可以在“胖 lozad”版本中包含它?
这是一个很好的建议,不过建议从 polyfill.io 加载填充程序,以便它只在不支持 IntersectionObserver API 的浏览器中加载,这样,已经支持该功能的浏览器就不必加载额外的代码了。
我真的很喜欢这个想法,但是您如何在 WordPress 或其他 CMS 中实现它呢?
您需要添加一些其他的魔法来操作应该“现在”显示但稍后应该延迟加载的图片。
当我第一次看到 Intersection API 时,这就是我想到的用例。只需要再添加几块拼图即可完成它。
您是否可以在加载时使用一些异步/延迟技巧来删除所有“src”属性值?我还没试过,但它可能会起作用……但感觉有点像黑客(我通常反对这种做法……)
我创建了一个粗略的 WordPress 插件,它使用 Lozad.js 的改版版本来延迟加载图片。它缺少一些设置,但它能工作,当 JS 被禁用时有一个备用方案,您可以在后端选择添加填充程序。您可以在此处找到该插件 https://github.com/aderaaij/wp-image-preload
它是否适用于通过 background-image 加载的背景图片?
是的,它适用于延迟加载背景图片,在如 使用 中所述,为要延迟加载的元素添加
data-background-image
属性。有趣图片延迟加载方法。不过,您可能需要小心横幅中的 Lotad 图片。最近任天堂对使用其知识产权的开发者并不友好。
当然,我会尽快解决这个问题。
感谢您提供此脚本!我希望很快看到它作为 WordPress 插件实现!:)
它看起来与 picture 元素不兼容?
Lozad.js 支持对响应式图片进行延迟加载,如果您想突出显示某个特定情况,请在 Github 上打开一个问题。
…与网站,并会导致“垃圾”(那种迟缓的感觉…
我认为应该是“jank”,而不是“junk”。
http://jankfree.org/
令我难以理解的是,为什么这么少的延迟加载器没有无 JavaScript 后备,也不支持图片元素和 srcset。以下是我所知的最棒的一个(尚未使用 Intersection Observer):https://github.com/tvler/lazy-progressive-enhancement
Lozad.js 常见问题 提到了无 JavaScript 后备。此外,它还支持响应式图像的延迟加载,阅读这里。
太棒了!抱歉,我并非暗示您的解决方案不支持这些功能,我只是在回复另一条关于
<picture>
的评论。感谢您的回复和插件,我期待着尝试使用它。我同意。一个具有包含 polyfill 选项的 WordPress 插件会很棒!
这很棒。不久前我在自己的延迟加载脚本 (https://github.com/malchata/yall.js) 中添加了
IntersectionObserver
支持,但我仍然回退到节流的滚动事件监听器。我很高兴人们使用IntersectionObserver
来实现这一点,因为它确实有助于减少 jank。继续努力,伙计。这如何与 SEO 支持配合使用?Google 会看到延迟加载的图像吗?
常见问题解答 回答了您的问题。
嘿,这太棒了。我很想看到它在 IE9 中运行。即使使用 Polifills,它也不起作用。您的演示也不起作用:https://apoorv.pro/lozad.js/demo/
如果有解决方案就好了!
谢谢,
Sebastian
请在 Github 上提交问题,我们会优先处理。
Apoorv,我喜欢这个库。但是,我无法忍受你徽标中的 Papyrus 字体。说真的,我甚至可以免费为你设计一个徽标。
我也有同样的想法。
感谢你提供帮助,Michael,我一定会联系你为 Lozad.js 2.0 设计徽标 :)。
太棒了,Apoorv,我是认真的。我很乐意帮忙。
只是想告诉大家。我是一位性能爱好者,在旧的 IE 浏览器中没有发现使用它的任何好处(至少在我的项目中没有)。以下是代码。
Lozad 是否与 React 和虚拟 DOM 兼容?
我在 npm 上找到了这个,但它似乎是一个空仓库 https://npmjs.net.cn/package/react-lozad
目前正在尝试解决页面加载时请求过多问题,希望利用您的脚本,但是由于 React 的特性,它似乎不起作用。
有什么建议吗?
谢谢!
是的,它与 React 兼容,无需任何其他模块。查看这个 https://codepen.io/PezCoder/pen/mBaOer
如果 src 链接失效怎么办?我从后端获取 data-src,并在 src 中设置了一个占位符,但即使后端链接不存在,占位符也会被替换。如何防止 Lozad 在没有 url 时将 src 中的占位符替换为 data-src 中的 url?
PS。在开发者工具中,我看到 src(unknown) data-loaded=”true”。
来自 Travis McGeehan 的使用 Lozad 的图片滑块