延迟加载图像的源占位符

dam*_*zzi 13 html javascript lazy-loading

我正在使用延迟加载机制,只有在用户视口中加载相关图像时才会加载.

为此,我定义了一个data-src链接到原始图像的属性和一个base64编码的占位符图像作为src属性,以使HTML有效.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-src="/path/to/image.png" alt="some text">
Run Code Online (Sandbox Code Playgroud)

我注意到chrome缓存了base64字符串但字符串很长并且使我的HTML膨胀(我在页面上有很多图像).

所以我的问题是,使用小的base64编码或1px x 1px占位符图像是否更好?

注意:对于SEO目的,元素必须是img.我的HTML也必须有效,因此src需要一个属性.

tho*_*chs 14

你可以在src标签中使用这个更短(但有效!)的图像(1x1像素GIF):

data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=
Run Code Online (Sandbox Code Playgroud)

请注意,如果你gzip你的HTML(你应该),字符串的长度将不那么重要,因为重复的字符串压缩得很好.

根据您的需要,您可能希望使用1x1像素的颜色(导致更短的gif文件).一种方法是使用Photoshop或类似工具以正确的颜色创建1x1像素GIF,然后使用ImageOptim等工具找到最佳压缩效果.有各种在线工具可将生成的文件转换为数据URL.


Dan*_*orn 7

我会在你的情况下使用占位符.

使用base64编码的图像类型会破坏延迟加载的目的,因为您仍然需要将一些图像数据发送到浏览器.如果任何事情可能对性能有害,因为图像是作为原始HTTP请求的一部分下载的,而不是通过浏览器可能使用图像标记和URL进行的单独请求.

理想情况下,如果它只是一个'加载'占位符或类似的东西,我会在CSS中创建它,然后当用户向下滚动以调用该特定图像的加载时,将其替换为加载的图像.


LSe*_*rni 7

我注意到 chrome 缓存了 base64 字符串,但字符串很长并且使我的 HTML 膨胀(我在页面上有很多图像)。

如果是这种情况,请考虑放置一个指向始终相同占位符的“真实”src 属性。您确实需要一个额外的 HTTP 请求,但是

  1. 几乎可以肯定,它会被流水线化并且花费很少的时间。
  2. 它会触发图像的缓存机制,它的base64并没有这样做,使得图像实际上将只有一次解码。考虑到今天的 CPU 和 GPU,这不是一个大问题,但无论如何。
  3. 它也将作为资源缓存,并且使用正确的标头,它将保留长时间,在来自同一客户端的所有后续页面点击中提供零加载时间。

如果页面上的图像数量很大,那么使用“真实”图像可能会更好。

我敢冒险它会更兼容浏览器、蜘蛛等等——广泛支持 base64 编码,但纯图像更是如此。

即使与您可以在 base64 中获得的最小图像相比,26 个字节也变成了这个

src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
Run Code Online (Sandbox Code Playgroud)

虽然你可以从

src="/img/p.png"
Run Code Online (Sandbox Code Playgroud)

一路到

src="p.png"
Run Code Online (Sandbox Code Playgroud)

这看起来很不臃肿 - 如果这样的词甚至存在的话。

测试

我已经运行了一个非常基本的测试

<html>
<body>
<?php
    switch($_GET['t']) {
        case 'base64':
            $src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';

            break;
        case 'gif':
            $src = 'p.gif';
            break;
    }
    print str_repeat("<img src=\"{$src}\"/>", $_GET['n']);
?>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我得到了:

images   mode      DOMContentLoaded   Load      Result
200      base64    202ms              310ms     base64 is best
200      gif       348ms              437ms
1000     base64    559ms              622ms     base64 is best
1000     gif       513ms              632ms
2000     base64    986ms             1033ms     gif is best
2000     gif       811ms              947ms
Run Code Online (Sandbox Code Playgroud)

所以,至少在我的机器上,我似乎给了你一个不好的建议,因为在你拥有近两千张图片之前,你看不到页面加载时间的优势。

然而:

  • 这在很大程度上取决于服务器和网络设置,甚至更多取决于实际的 DOM 布局。
  • 我只对每一组进行了一个测试,这是糟糕的统计数据,使用 Firebug,这是糟糕的方法 - 如果你想获得可靠的数据,请使用一些 Web 性能监控工具和真实数据的克隆在任一模式下运行几十个页面加载页。
  • 使用 PNG 而不是 gif 怎么样?