Why should you encode images in web applications as base64?

March 9, 2012 at 11:58

Website weight loss?

A skilled young developer posted this recently on Twitter:

Well, yes, base64-encoding and embedding the image into HTML is one way to reduce HTTP requests, but honestly, why would anyone do this?

This article will describe briefly how base64 encoding is done and what benefits it might have.

By base64 encoding images, he means inserting HTML images like this:

<img src=”data:image/png;base64,[BASE64]“/>

Where [BASE64]  is a base64 string generated from the file with a tool like this here.

What this effectively does is that it embeds the entire content of the image into the HTML itself. This means that the browser that visits the website has to do one less HTTP request that it would otherwise do to get the file. HTML file itself would be larger as a result since it also includes the image file. The reason why the question is asked though is because if the HTML itself is not cached, then every time user requests the page they have to re-download the entire content, defeating the purpose, since browsers would otherwise cache the image and make subsequent requests on the websites faster if the same image is displayed in HTML again.

So why should you do it?

Reducing the amount of HTTP requests is a seriously important issue. If your website includes a lot of different files (JavaScript, CSS, fonts and images) and has a lot of users (especially new users) at the same time, then your site will slow down very quickly and might even cause problems for the server. To help with this, a lot of frameworks combine CSS and JavaScript files automatically and it is recommended to do this yourself as well even if you don’t use a framework. But images still make a huge chunk of an average website request, so encoding some images in base64 can give you quite a bit of performance gain should your site become suddenly popular.

But  can I back up my claim?

First of all, it is not recommended to use base64 encoded images in inline HTML, unless browser is able to cache this information in any way. But there is an alternative: you can embed images and fonts inside CSS file, effectively making your entire web ‘design’ into a single CSS file. It’s not useful to do this right away and not for all files and debugging will be rather difficult once you do this, but you should do it only once you’re not ‘developing’ the site anymore and don’t need to change font or graphics files around. Basically when you are ready to deploy your website and go live. It’s useful for all little parts of your code, like custom bulletins, some repeatable background images and so on.

As a result, single images in HTML (like galleries and other content pictures) will still make their own requests while website design will be stored in a single CSS file.

Anyways, just because I was curious, I made a little test since I was worried about how this might affect the situation when Gzip is used to compress CSS (usually it is not recommended to Gzip image content since they are already compressed). I built two examples on my WWW framework which automatically Gzips non-image output sent to the browser:

Test A was done with base64 encoding used in images and Test B was done without base64 encoding. HTML of both tests were the same:

<div id=”div1″ style=”width:240px;height:240px;”></div>
… and #div2-#div10 just like above …

Test A had a CSS as follows ([BASE64] again was the long custom string generated with the tool shown above):

#div1 { background-image:url(“data:image/png;base64,[BASE64]“); }
… and #div2-#div10 just like above …

Test B had CSS like:

#div1 { background-image:url(“image1.jpg”); }
… and #div2-#div10 just like above …

Both examples included ten JPEG images of 240×240 pixels in size. This is far more picture content than you’d expect from an average website design, but works really well as an extreme example for current tests.

Results:

Test A does 8 HTTP requests, including HTML, three CSS files and four JavaScript files. Test B does 18 HTTP requests, including all of what was in Example A, but also 10 JPEG image files. In both cases, JavaScript and CSS and HTML are Gzip encoded. I did 12 tests on both scripts without cache being used. I then removed 2 tests from both sets that were the slowest, since sometimes server lags and would throw off the averages. Tests were done and measured by Google Chrome.

Test B, where base64 encoding was not used to include image files in CSS, had the average time to render the page as 668ms.

Test A, where images were encoded in base64, had the average time to render the page as 463ms, almost 30% faster while also making 10 HTTP requests less on the web server.

So the benefits are certainly there, but the benefits are there only for cases where content can be cached. As I said above, there’s no point to base64 images into HTML that is not cached. If HTML is not cached, do not use base64. No point using base64 for embedding galleries and other content pictures. But for website design? Yes. 30% victory in processing time and a lot less HTTP requests after all.

Hopefully this helped a little.


Tags:

3 Responses to “Why should you encode images in web applications as base64?”

  • Ando says:

    Some background on my (a bit) ranting tweet…

    …which was about a page where a 630KB image was (most likely) pasted into CKEditor that turned it into a base64 encoded string, saved it in MYSQL, which was then in turn used to render the site content.

    To top that, when you right click and choose View Image (or similar), your browser (Firefox) will use the base64 string on it’s URL bar to render the image – and that’s not very efficient (arguably), since for the 30 seconds it took to un-freeze, I feared I’d have to kill Xorg and loose my unsaved work.

    So, base64 encoding large (both in terms of file size and dimensions) images is not the optimum way to go about things. You could even call it a virtual booby-trap.

    A note: while it’s certainly advisable to cut costs (request rate) when dealing with large loads, it’s not worth the trouble when you’re building small, namecard type websites where the sole purpose is to make a presence in the web. You could host a hundred of these sites and not suffer from 10 * 100 = 1000 extra HTTP requests when the average visitor count in one day is ~10 – 20.

    That being said, I was quite satisfied with your essay about why this might be a good idea. Reading the article saved me from blind judgement based on one negative experience.

  • Kristo Vaher says:

    Agreed :)

    I tend to work on large projects and haven’t used base64 encoding yet. This is really micro-optimization that has a benefit in larger scale only (read: viral scale).

    But yes, I ended up writing the article due to my absolute obsession with performance and getting the very best out of as few server resources as possible.

  • Ray Claunch says:

    Nice read. This blog is awesome.

Leave a Reply

You must be logged in to post a comment.