延迟加载图像的源占位符

时间:2022-11-03 22:31:22

I'm using a lazyload mechanism that only loads the relevant images once they're in the users viewport.

我正在使用一种惰性加载机制,只有当它们位于用户视口中时才会加载相关图像。

For this I've defined a data-src attribute which links to the original image and a base64 encoded placeholder image as src attribute to make the HTML valid.

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

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-src="/path/to/image.png" alt="some text">

I noticed that chrome caches the base64 string but the string is quite long and bloats my HTML (I have a lot of images on a page).

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

So my question is if it's better to use a small base64 encoded or a 1px x 1px placeholder image?

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

Note: For SEO purposes the element must be an img. Also my HTML must be valid, so a src attribute is required.

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

4 个解决方案

#1


6  

I'd use the placeholder in your situation.

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

Using the base64 encoded image kind of defeats the purpose of lazy loading since you're still having to send some image data to the browser. If anything this could be detrimental to performance since the image is downloaded as part of the original HTTP request, rather than via a separate request as a browser might make with an image tag and URL.

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

Ideally if it's just a 'loading' placeholder or something similar I'd create this in CSS and then replace it with the loaded image when the user scrolls down sufficiently as to invoke the loading of that particular image.

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

#2


9  

You can use this shorter (but valid!) image in the src tag (1x1 pixel GIF):

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

data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=

Note that if you gzip your HTML (which you should), the length of the string won't be that important because repetitive strings compress well.

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

Depending on your needs you might want to use a color for the 1x1 pixel (results in shorter gif files). One way to do this is using Photoshop or a similar tool to create the 1x1 pixel GIF in the right color, and then using a tool like ImageOptim to find the best compression. There's various online tools to convert the resulting file to a data URL.

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

#3


4  

I noticed that chrome caches the base64 string but the string is quite long and bloats my HTML (I have a lot of images on a page).

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

If that is the case, consider placing a 'real' src attribute pointing to always the same placeholder. You do need an extra HTTP request, but:

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

  1. it will be almost certainly pipelined and take little time.
  2. 它几乎肯定是流水线的,花费的时间很少。

  3. it will trigger the image caching mechanism, which base64 does not do, so that the image will actually be only decoded once. Not a great issue given today's CPUs and GPUs, but anyway.
  4. 它将触发图像缓存机制,base64不会这样做,因此图像实际上只会被解码一次。对于今天的CPU和GPU而言,这不是一个很大的问题,但无论如何。

  5. it will also be cached as a resource, and with the correct headers, it will stay a long time, giving zero load time in all subsequent page hits from the same client.
  6. 它也将作为资源缓存,并且使用正确的标头,它将保持很长时间,在来自同一客户端的所有后续页面命中中提供零加载时间。

If the number of images on a page is significant, you might easily be better off with a "real" image.

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

I'd go as far as to venture that it will be more compatible with browsers, spiders and what not -- base64 encoding is widely supported, but plain images are even more so.

我敢去冒险它会更加兼容浏览器,蜘蛛和什么不兼容 - base64编码得到广泛支持,但普通图像更是如此。

Even compared with the smallest images you can get in base64, 26 bytes become this

即使与base64中可以获得的最小图像相比,也可以使用26个字节

src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="

while you can go from

虽然你可以去

src="/img/p.png"

all the way to

一直到

src="p.png"

which looks quite unbloaty - if such a word even exists.

看起来很无趣 - 如果这样的话甚至存在。

Test

I have ran a very basic test

我做了一个非常基本的测试

<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>

and I got:

我得到了:

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

So, at least on my machine, it would seem I'm giving you a bad advice, since you see no advantages in page load time until you have almost two thousand images.

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

However:

  • this heavily depends on server and network setup, and even more on actual DOM layout.
  • 这在很大程度上取决于服务器和网络设置,甚至更多依赖于实际的DOM布局。

  • I only ran one test for each set, which is bad statistics, using Firebug, which is bad methodology - if you want to have solid data, run several dozen page loads in either mode using some Web performance monitoring tool and a clone of your real page.
  • 我只使用Firebug为每个集合运行了一次测试,这是一个糟糕的统计数据,这是一种糟糕的方法 - 如果你想拥有可靠的数据,可以使用一些Web性能监控工具和真实的克隆在任一模式下运行几十个页面加载页。

  • (what about using PNG instead of gif?)
  • (那么使用PNG而不是gif?)

#4


1  

I've experienced good results with inline SVG for responsive image placeholders as described here.

对于响应式图像占位符,我已经使用内联SVG获得了良好的结果,如此处所述。

Basically, you put something like

基本上,你把类似的东西

data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' width%3D'500' height%3D'500' viewBox%3D'0 0 500 500'%2F%3E

in your <img>'s src attribute. Beware to keep width, height and viewBox values on par with your real image dimensions. This way your layout won't jump around thus causing unnecessary repaints.

延迟加载图像的源占位符的src属性中。注意保持宽度,高度和viewBox值与您的真实图像尺寸相同。这样你的布局就不会跳转,从而造成不必要的重绘。

#1


6  

I'd use the placeholder in your situation.

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

Using the base64 encoded image kind of defeats the purpose of lazy loading since you're still having to send some image data to the browser. If anything this could be detrimental to performance since the image is downloaded as part of the original HTTP request, rather than via a separate request as a browser might make with an image tag and URL.

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

Ideally if it's just a 'loading' placeholder or something similar I'd create this in CSS and then replace it with the loaded image when the user scrolls down sufficiently as to invoke the loading of that particular image.

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

#2


9  

You can use this shorter (but valid!) image in the src tag (1x1 pixel GIF):

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

data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=

Note that if you gzip your HTML (which you should), the length of the string won't be that important because repetitive strings compress well.

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

Depending on your needs you might want to use a color for the 1x1 pixel (results in shorter gif files). One way to do this is using Photoshop or a similar tool to create the 1x1 pixel GIF in the right color, and then using a tool like ImageOptim to find the best compression. There's various online tools to convert the resulting file to a data URL.

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

#3


4  

I noticed that chrome caches the base64 string but the string is quite long and bloats my HTML (I have a lot of images on a page).

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

If that is the case, consider placing a 'real' src attribute pointing to always the same placeholder. You do need an extra HTTP request, but:

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

  1. it will be almost certainly pipelined and take little time.
  2. 它几乎肯定是流水线的,花费的时间很少。

  3. it will trigger the image caching mechanism, which base64 does not do, so that the image will actually be only decoded once. Not a great issue given today's CPUs and GPUs, but anyway.
  4. 它将触发图像缓存机制,base64不会这样做,因此图像实际上只会被解码一次。对于今天的CPU和GPU而言,这不是一个很大的问题,但无论如何。

  5. it will also be cached as a resource, and with the correct headers, it will stay a long time, giving zero load time in all subsequent page hits from the same client.
  6. 它也将作为资源缓存,并且使用正确的标头,它将保持很长时间,在来自同一客户端的所有后续页面命中中提供零加载时间。

If the number of images on a page is significant, you might easily be better off with a "real" image.

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

I'd go as far as to venture that it will be more compatible with browsers, spiders and what not -- base64 encoding is widely supported, but plain images are even more so.

我敢去冒险它会更加兼容浏览器,蜘蛛和什么不兼容 - base64编码得到广泛支持,但普通图像更是如此。

Even compared with the smallest images you can get in base64, 26 bytes become this

即使与base64中可以获得的最小图像相比,也可以使用26个字节

src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="

while you can go from

虽然你可以去

src="/img/p.png"

all the way to

一直到

src="p.png"

which looks quite unbloaty - if such a word even exists.

看起来很无趣 - 如果这样的话甚至存在。

Test

I have ran a very basic test

我做了一个非常基本的测试

<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>

and I got:

我得到了:

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

So, at least on my machine, it would seem I'm giving you a bad advice, since you see no advantages in page load time until you have almost two thousand images.

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

However:

  • this heavily depends on server and network setup, and even more on actual DOM layout.
  • 这在很大程度上取决于服务器和网络设置,甚至更多依赖于实际的DOM布局。

  • I only ran one test for each set, which is bad statistics, using Firebug, which is bad methodology - if you want to have solid data, run several dozen page loads in either mode using some Web performance monitoring tool and a clone of your real page.
  • 我只使用Firebug为每个集合运行了一次测试,这是一个糟糕的统计数据,这是一种糟糕的方法 - 如果你想拥有可靠的数据,可以使用一些Web性能监控工具和真实的克隆在任一模式下运行几十个页面加载页。

  • (what about using PNG instead of gif?)
  • (那么使用PNG而不是gif?)

#4


1  

I've experienced good results with inline SVG for responsive image placeholders as described here.

对于响应式图像占位符,我已经使用内联SVG获得了良好的结果,如此处所述。

Basically, you put something like

基本上,你把类似的东西

data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' width%3D'500' height%3D'500' viewBox%3D'0 0 500 500'%2F%3E

in your <img>'s src attribute. Beware to keep width, height and viewBox values on par with your real image dimensions. This way your layout won't jump around thus causing unnecessary repaints.

延迟加载图像的源占位符的src属性中。注意保持宽度,高度和viewBox值与您的真实图像尺寸相同。这样你的布局就不会跳转,从而造成不必要的重绘。