延迟加载图像以获得最佳性能的最佳方法

2025-05-26

延迟加载图像以获得最佳性能的最佳方法

图片延迟加载是网站优化中较为流行的方法之一,因为它实现起来相对简单,并且性能提升显著。使用延迟加载,我们会异步加载图片,这意味着我们只会在图片出现在浏览器视口中时才加载它们。

大约一年前,Chrome 和其他主流浏览器发布了原生的图片和 iframe 延迟加载功能。该功能旨在让浏览器能够控制何时请求图片或 iframe 资源,从而简化开发工作。在此之前,唯一的选择是使用各种 JavaScript 插件来监控视口变化并动态加载资源。现在,浏览器可以原生地实现这些功能了!

在撰写本文时,大约73% 的当前使用的浏览器支持此功能,这还不错,但我们不想让 27% 的潜在用户无法访问和使用网站图像内容。

因此,这让我们陷入了一个有趣的境地:

  • 我们希望利用原生延迟加载的优势,让支持它的浏览器也能享受到它的优势
  • 我们希望使用 JS 插件作为不支持延迟加载的浏览器的后备
  • 如果浏览器支持原生延迟加载,我们不想加载延迟加载 JS 插件。
  • 必须同时支持img和元素source

“loading”属性

我们有三个可能的值可用于loading属性。

  • auto- 默认值。与不设置该属性相同。
  • eager- 立即加载资源。
  • lazy- 一旦资源进入视口,就加载它。

虽然这取决于用例,但通常我们希望使用eager首屏上方资源的价值和lazy首屏下方资源的价值。

现代方法

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

图像标记

我们希望 JavaScript 函数能够基于原生延迟加载功能的支持来启动图片加载过程。为此,我们将图片路径添加到 而data-src不是src。但我们不应该src留空,所以我们将使用 1x1px 的透明图片占位符。我们的img元素标记如下所示

 <img 
    src="/path/to/placeholder/image.png"
    data-src="/path/to/full/image.jpg"
    alt="Image description"
    class="lazyload"
    loading="lazy"
/>
Enter fullscreen mode Exit fullscreen mode

请注意,class="lazyload"是 lazyload fallback 插件使用的。我之前用过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>
Enter fullscreen mode Exit fullscreen mode

特征检测

我们需要检测用户的浏览器是否支持原生延迟加载。幸运的是,我们可以直接使用 JavaScript 来实现。

   if ("loading" in HTMLImageElement.prototype) {
      /* Native lazy loading is supported */
   } else {
      /*  Native lazy loading is not supported */
   }
Enter fullscreen mode Exit fullscreen mode

最终的 JavaScript 代码

对于原生的延迟加载,我们只需要和元素data-src赋值,剩下的交给浏览器处理。srcimgsource

对于不支持的浏览器,我们只需加载 JavaScript 插件,并根据需要运行它(如果插件没有自动运行)。我使用了lazysizes,但任何插件都可以,只需确保标记正确(类名、数据元素等)。

因此最终的 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>
Enter fullscreen mode Exit fullscreen mode

提升性能和 Lighthouse 评分

在我的个人网站上,我使用了一个 JavaScript 插件来实现所有浏览器的图片延迟加载。实施这个现代化方法后,我省去了网站加载时加载和解析的一个 JavaScript 文件,这反而提升了我的 Lighthouse 评分和整体性能!

替代文本

更多图像优化技术以实现最佳性能

延迟加载是优化 Web 图像性能的众多方法之一。我撰写了一篇深入的文章,涵盖了 Web 图像优化的其他重要技术和方面,例如 Web 特定的图像格式、使用 CDN、渐进式图像等等。


这些文章都是咖啡带来的灵感。所以,如果你喜欢我的文章,觉得它有用,不妨请我喝杯咖啡!我会非常感激的。

给我买杯咖啡

感谢您花时间阅读这篇文章。如果您觉得它有用,请点赞 ❤️ 或 🦄,分享并评论。

文章来源:https://dev.to/prototyp/best-way-to-lazy-load-images-for-maximum-performance-27o1
PREV
在 React 中实现骨架加载
NEXT
我的个人资料网站现在是一个终端