Blank image. What to use: Base64 vs 1x1 JPEG image

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.


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


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.