11

I am building a website and I want to make HTTP queries as few as possible for a better website speed and seo. The page I just created is showing images on scroll (images have an attribute data-scr which is converted to src when the user scrolls down at the respective image).

Because all images have the data-src attribute instead of src, W3C shows me errors.

At this moment I found two options, to solve this problem:

  1. The initial src of all images to be an url of a blank 1x1 image
  2. The initial src of all images to be a data base 64 blank image

When I am using an URL of a blank 1x1 image, then (tested with tools.pingdom.com) it shows 1 HTTP request. When I am using a data base64 blank image then it shows as many requests as the number of images on page.

Which of them is the more efficient way, for a website faster speed and makes fewer HTTP requests? (let's suppose that the user is loading the webpage at a 14.4kbps internet speed - first internet speed).

But for SEO?

Is there any other option?

  • 8
    "When I am using a data base 64 blank image then it shows as many requests as the number of images on page." - there's something a bit wrong there? The whole point of using a data-URI is that there is no external HTTP request. (Only user-agents that don't understand data-URIs might fire an HTTP request.) – MrWhite Apr 15 '16 at 9:09
  • If the blank image will be bigger than 1x1 px (I guess it is), I would recommend a bigger background image (10x10 px, 100x100 px) because rendering will be faster. – totymedli Apr 15 '16 at 14:19
  • 3
    Use none? You could create the img tag dynamically at the same time you convert data-src to src. Instead of having blank image with a data-src, you could store the list of images and generate the tag when needed. – the_lotus Apr 15 '16 at 15:08
  • @Pharap that doesn't work because the browser will download the images even if they are hidden. – DisgruntledGoat Apr 15 '16 at 18:25
  • Whichever you choose for delivering the content, encoding it as a png8 will probably be faster than JPEG. – symcbean May 21 '16 at 23:28
12

The base64 image option should be used where you would only have a very small number of images and you want to eliminate the network overhead of fetching a picture from the server. However from what you are indicating in the question I assume this could scale to a large number of images. In this case I would use a single 1px x 1px transparent image from the server with a long cache lifetime as it will be fetched from the server once then cached in the browser and any intermediate proxy servers.

As an example this image would be around 95 bytes in size (https://commons.wikimedia.org/wiki/File:1x1.png), for a base64 encoded image string you would find the size would be on par with this image file size but would be repeated for every single image you add it to.

For 2-5 images the size and speed would be negligible and would decrease server traffic by eliminating one whole fetch, but for more than that the page size would start to get too large which would affect loading times and in turn SEO ranking.

  • 6
    A blank base64 image could have 55 bytes: data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=. If the URL of the image is a bit longer (ex: example.com/templates/template-name/files/1x1.png), the base64 image will be recommended because you don't make HTTP queries and it is smaller in bytes than image URL (repeated for each image on the page) + the external image size. – NETCreator Hosting Apr 15 '16 at 4:36
  • @NETCreatorHosting-WebDesign Thank you for your comment. I compared the website size when using a base64 image and an external image, and the size is smaller when using a base64 image. I am using around 40 images per page. – MM PP Apr 15 '16 at 4:43
  • Or you can upload the image on your website root and use a relative url, so the website will be much smaller. – NETCreator Hosting Apr 15 '16 at 4:46
  • 3
    gzip will take care of the repetitions, so having 400 base-64 encoded images in your page will not cost more bandwidth than 400 URLs of images. – user2428118 Apr 15 '16 at 7:31
  • 3
    @Aron If your page is 25.6 MB large (400 82-byte long data URI's with 64kB between them = 25,568,800 bytes), you've got bigger problems to worry about than 32.8 kB of base64-encoded images. – user2428118 Apr 15 '16 at 12:00
5

Definitely go with the data URI, unless you need support for IE < 8. (Browser support.)

Embedding lots of tiny images directly in the HTML may look like it will take up more bandwidth than linking to them directly, but the increase will be mitigated by gzip; the only difference in the page's size will come from the difference in length between one data URI of a blank image and one URL of the image on your server. A blank GIF can be as small as 43 bytes. Base 64-encoded, that's 82 bytes. There's no way that's ever going to perform worse than a > 500-byte HTTP request, a similarly-sized response, and then I'm not even taking TCP packet size and other overhead into account.

Here is the Base 64-encoded 43-byte GIF image:

data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

As for SEO, have a look at the source code of a Google site, for example Google News, and search for data:image/gif,base64

  • Your image is large. Check comment above for 55 byte version. – Joshua Apr 15 '16 at 15:21
  • 1
    This answer on StackOverflow with reported tests (May 2014) appears to show that embedding large numbers (~1800) of 1px images is considerably slower than linking repeatedly to the same external image. The external image is requested once and cached, whereas the browser must decode every data-URI separately as part of the HTML parsing process - this would seem to be the bottleneck. This would seem to suggest that data-URIs should be limited to a small number of (small) images. – DocRoot Apr 16 '16 at 12:22
  • @Joshua Although that image displays correctly in my browser (Firefox), it can't be opened by some other programs (e.g. Paint) so I'd avoid using it. – user2428118 Apr 16 '16 at 18:33
2

At this moment I found two options, to solve this problem: The initial src of all images to be a data base 64 blank image

This option not only requires a modern browser, but it can be slower on the client side since the browser must base-64 decode the image data in order to produce the image.

The initial src of all images to be an url of a blank 1x1 image

It's an O.K. move provided that the blank image URL for all image slots is exactly the same URL and that it has a long cache lifetime defined in the HTTP header "cache-control". The problem with this is that as the new image files load, the image squares will jump to the new size which could make the user experience not as wonderful.

The almost perfect idea is this...

When page starts up, present a grid with fixed-size boxes that can accomodate each image. It is ok if the entire grid does not fit on the screen. Then create javascript that executes after the HTML loads, and in that javascript, create a new image element and attach it to each cell of the grid then set the source of the image to the correct image file. Do this until the first screen fills up. then detect scrolling within javascript and then when scrolling happens, repeat the above process for the new cells.

Now if you want the best of the best, and quality isn't a huge concern, then what I recommend (that I also implemented on my site) is to construct a grid and set it such that the background image of that grid is a sprite sheet of all of the images formatted as squares of images. This method is flexible and fast to load since one request is required for all images.

Here's a template HTML to use if you want to go the fast route. Only two requests are made. The HTML code, and the one image. In this code, I assume each image from the sheet is 100 pixels in width and 200 pixels in height and that each image is perfectly aligned next to each other with no gaps.

<html>
<head>
<style type="text/css">
#imagegrid {background-color: black; background-image:url('http://example.com/url/to/imagesheet.jpg');}
A {display:block;width:100px;height:200px;margin:10px;float:left;}
#image1{background-position: 0px 0px}
#image2{background-position: 100px 0px}
#image3{background-position: 200px 0px}
...
#imageN{background-position: XXXpx 0px}
</style>
</head>
<body>
<div id="imagegrid">
<a href="image_one.htm" id="image1"></a>
<a href="image_two.htm" id="image2"></a>
<a href="image_three.htm" id="image3"></a>
...
<a href="image_N.htm" id="imageN"></a>
</div>
</body>
</html>

In my code I added 3 dots. That means you can keep adding images by incrementing the numbers and by incrementing the position by 100 each time provided that your sprite sheet has only one row of images. Also, with some browsers such as Opera, you might need to add a negative sign in front of the background position values to get them to work.

  • 2
    Unless your images are half a gigabyte in size, there is no way that base64-decoding an image will have any measurable impact on performance. – user2428118 Apr 15 '16 at 8:39
  • It also depends on the computer system too. If the client still has an old-fashioned computer such as a pentium 1, then there may be a performance hit. – Mike Apr 15 '16 at 23:23
1

The image, because maintainability.

In my experience it works better to use the image. This is more obvious in the actual code and easier to remember. I doubt you'll remember the encoded string for a transparant image, and even if you do, your succesors/collegaes.
If you come back to this code after a few weeks, you've forgotted the base64.

It'll be a lot simpeler to maintain the code if you use the image, the minimal pro's do not weight up to this.

  • Many people use scripts to generate base-64 values, so the requirement to remember such values is out of the window unless the OP happens to use only a set of HTML files to represent the code of his website. – Mike Apr 15 '16 at 23:29
1

How about only ~3 extra bytes, 0 extra http requests, and 0 extra img src length (or 0 uncached data-image placeholders). Can you use a blank src for image?

<img src data-src="banannanannas.jpg" />

And if they have alt tags you can hide those from error/fail image:

<img src data-src="banannanannas.jpg" onerror="this.alt=''" alt="some desc" />

Displays: nothing. Hacking off the alt tag has a slight FOUC delay from image placeholder border. Perhaps that can be cleaned off as well.

  • 2
    Although an empty src attribute will still throw errors in the W3C Validator (which seems to be the concern). – MrWhite Apr 15 '16 at 19:25
  • @w3dk Yeah that sucks, but then again very few modernizations pass. – dhaupin Apr 15 '16 at 19:32
  • If you want to pass W3C rules, something needs to be specified for the src, even if its a URL that returns a 404 error. I'd also recommend specifying the values of the width and height attributes for the image so that users see actual placeholders at first instead of tiny boxes that inflate halfway through the loading process. – Mike Apr 15 '16 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.