Caching page: base64 image in HTML vs Image as attachment (separate URL)

Comments

3 comments

  • Austin Spires

    @mkowalski this is a pretty interesting question. I'll see if I can pull in some of our perf team to weigh in. Both of these scenarios are possible to do, but I don't know the full performance implications myself.

  • Steve Souders

    The question of whether to inline resources or keep them as external files comes up often when optimizing web performance. Your question is about images, but the same question comes up for JS & CSS - every inline SCRIPT or STYLE block could instead be a separate file. What's the best choice - inline or external? It's a hard question to answer in the abstract - often it comes down to the type of page and session metrics (page views per session, sessions per month, etc.). Generally the answer is: small files should be inlined, large files should be served separately. But we can dig into some of the tradeoffs of your question in more detail.

    The biggest issue with your scenario is the limit on the size of base64 URIs. IE8 has a 32K limit. Opera 11 is ~64K. The data URL spec mentions that attributes (such as "src") have more stringent limits of 1-2K. You're likely to run into issues across major browsers if you try to base64 encode a 5M image.

    Besides the size limitations, even an image > 10K or so will have negative tradeoffs if it's inlined. A big factor here is whether the HTML response is cacheable, and how often people revisit the HTML page. For example, if an HTML response is cacheable for a year, then there are advantages of embedding the image. But the more typical case is that HTML is not cacheable (by the browser), and so it's almost always re-loaded. In this case, embedding the image (even at just 10K) will dramatically increase the size of the document on every page view, and it would be better to serve the image as a separate file that is cacheable.

    There are some optimizations that are a compromise of inline in every HTML document vs each image as a separate HTTP request. 1) You can inline all the images in a stylesheet, and load them as background images via CSS. This is a good tradeoff if you have multiple images as it can collapse multiple HTTP requests into a single HTTP request. 2) You can do "dynamic inlining" to only reference the external files when it's likely they're already in the user's browser cache.

    If your HTML is not cacheable and the images are bigger than a KB or so, it's probably better to keep them as external files.

  • edmundhuber

    Here are some reasons to not use datauris:

    • The browser won't be creating DOM elements while it's busy fetching all that base64.

    • base64 (in the datauri) is a less efficient encoding than binary (as stored in an image file).

    • The inlined image can't be cached and used again in a different page.

    That being said, please have a good look at Steve's suggestion about using the cookie trick to decide to use inlined images or separate images. If you have the time to build that in, that would give you the best of both worlds.

Please sign in to leave a comment.