Isn’t it silly that a tiny favicon requires yet another HTTP request? How to make favicon go into a sprite?

Isn’t it silly that a tiny favicon requires yet another HTTP request? How to make favicon go into a sprite?

Everybody knows how to setup a favicon.ico link in HTML:

But I think it is just silly that for a tiny several-byte icon you need yet another HTTP request. So I wondered, how could I make that image part of a sprite (e.g. background-position=0px -200px;) in order to speed up and save that valuable HTTP request: how could I tackle this and get it into the rest of my existing image sprite with my logo and my other artworks?
The robot pointing to favicon.ico, item nr.31 on the waterfall graph, is my pet ZAM, he’s often happier and he has a good point letting me know its time for some creative upgrades on the web, though he and I don’t agree on his outfit, which I think is a bit silly today…

Solutions/Answers:

Solution 1:

A minor improvement to @yc’s answer is injecting the base64-encoded favicon from a JavaScript file that would normally be used and cached anyway, and also suppressing the standard browser behavior of requesting favicon.ico by feeding it a data URI in the relevant meta tag.

This technique avoids the extra http request and is confirmed to work in recent versions of Chrome, Firefox and Opera on Windows 7. However it doesn’t appear to work in Internet Explorer 9 at least.

index.html

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <!-- Suppress browser request for favicon.ico -->
        <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
        <script src="script.js"></script>
...

script.js

var favIcon = "\
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABrUlEQVR42mNkwAOepOgxMTD9mwhk\
[...truncated for brevity...]
IALgNIBUQBUDAFi2whGNUZ3eAAAAAElFTkSuQmCC";

var docHead = document.getElementsByTagName('head')[0];       
var newLink = document.createElement('link');
newLink.rel = 'shortcut icon';
newLink.href = 'data:image/png;base64,'+favIcon;
docHead.appendChild(newLink);

/* Other JS would normally be in here too. */

Demo: turi.co/up/favicon.html

Solution 2:

I think for the most part it does not result in another HTTP request as these are usually dumped in the browser’s cache after the first access.

This is actually more efficient than any of the proposed “solutions”.

Solution 3:

You could try a data URI. No HTTP request!

<link id="favicon" rel="shortcut icon" type="image/png" href="data:image/png;base64,....==">

Unless your pages have static caching, your favicon wouldn’t be able to be cached, and depending on the size of your favicon image, your source code could get kind of bloated as a result.

Data URI favicons seems to work in most modern browsers; I have it working in recent versions of Chrome, Firefox and Safari on a Mac. Doesn’t seem to work in Internet Explorer, and possibly some versions of Opera.

If you’re worried about Old IE (and you probably shouldn’t be these days), you could include an IE conditional comment that would load the actual favicon.ico in the traditional way, since it seems that older Internet Explorer doesn’t support Data URI Favicons

`<!--[if IE ]><link rel="shortcut icon" href="http://example.com/favicon.ico"  type="image/x-icon" /><![endif]--> `
  1. Include the favicon.ico file in your root directory to cover browsers that will request it either way, since for those browsers, if they’re already checking no matter what you do, you might as well not waste the HTTP request with a 404 response.

You could also just use the favicon of another popular site which is likely to have their favicon cached, like http://google.com/favicon.ico, so that it is served from cache.

As commenters have pointed out, just because you can do this doesn’t mean you should, since some browsers will request favicon.ico regardless of the tricks we devise. The amount of overhead you’d save by doing this would be minuscule compared to the savings you’d get from doing things like gzipping, using far-future expires headers for static content, minifying JavaScript files, putting background images into sprites or data URIs, serving static files off of a CDN, etc.

Solution 4:

You could use base64 encoded favicon, like:

<link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAACbUlEQVRIx7WUsU/qUBTGv96WSlWeEBZijJggxrREdwYixMnByYEyOvgfsBAMG0xuDsZ/QGc3NDFhgTioiYsmkhBYGLSBkLYR0va8gSjvQXiIT7/l5ibfOd/v3pN7gSmVSMTj8ThRfzdYk8lkMpl83/+AVFVVVXU0eHiVJEmSpB8DIcpkMplsdhCYz+fzhQJROBwOh8PDQN+oQCAQCASIRFEURZHI45GkP0/e7Xa73e70AMJnjel0Op1OA6oaDB4eAkAw6PcDvZ5t6zrw/Hx2trAw/cHYZ426ruu6DtzcGEYuBzQa19etFvD4WKtls4AoRqMPDwBjjLGPrt84ilgsFovF6EOapmmaRiP6O/jbAIguL4vFYpHGqlKpVCoVomq1Wq1Wibxer9fn+w+Q9+cUiUQikQhNrfdgWZZlWf4yyGhj27Zt254MUK/X6/X6F0aiKIqiKIOCYRmGYRjGZADLsizLIgqFQqHV1SkAnp5OTn79ItK0qyuPZ7SxaZqmaU4GKJfPzxmbfAPc/f3pqaIQLS8vLtZqgOP0bYyJoiAARC5Xrwf4/Vtbb2+Th1YqlUqlErC01GgkEkCz2WxyHLC+LsuiCAiCJLlcgM+3vd3pcBzXaJTLR0dEs7Ptdv+D4TiOG/A6DsBxQKvV621sAGtru7vl8ngAjuvXv7xcXIgiwNjMjCj2h+k4fQfPA4LA8xwHCO323V2hABiG223bwPy8xwMAbvfcHGMAY32j47y+3t4OAsZpZ2dzEwAsy7IcBxAExhwHMIxOx3GAlZVUyjT/1WFIudzenstFlEpFo9M8o+Pj/X2eJzo4SCR4fnzdb2N4Pyv9cduVAAAAAElFTkSuQmCC" rel="icon" type="image/x-icon" /> 

Solution 5:

Good point and nice idea, but impossible. A favicon needs to be a single, separate resource. There is no way to combine it with another image file.

Solution 6:

I found an interesting solution on this page. It’s in German but you will be able to understand the code.

You put the base64 data of the icon into an external stylesheet, so it will be cached. In the head of your website you have to define the favicon with an id and the favicon is set as a background-image in the stylesheet for that id.

link#icon {
  background-image:url("data:image/x-icon;base64,<Daten>");
}

and the html

<html>
    <head>
      ...
      <link id="icon" rel="shortcut icon" type="image/x-icon" />
      <link rel="stylesheet" type="text/css" href="/style.css" />
      <!--[if lt IE 8]>
      <style type="text/css">
        link#icon { background-image:url("/favicon.ico"); }
      </style>
      <![endif]-->
      ...
    </head>
    <body>
      ...
    </body>
  </html>