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


#1

Background:

We want to build a page that will use dynamic serving (different version for desktop, tablet and mobile).

Currently we think which of the two solutions will serve content faster and be better overall.
I am thinking in context of serving it to different devices (desktop, tablet, mobile) using the same URL.

Dynamic serving sites: one URL that serves different HTML and CSS depending on the user agent.

source: http://www.vervesearch.com/blog/the-ultimate-guide-to-developing-mobile-websites/

Our main goal is speed. Then other things.


Solutions:

  1. storing images as base64 in HTML

User enters a site. For example it contains 1-2 images that are pretty large. Images are embedded directly into HTML as base64.
We have one minified JS file and one minified CSS file.
So in ideal example we have

  • HTML that contains 1-2 large images (they can have up to 5MB).
  • one minified CSS file
  • one minified JS file

So…
3 requests

  1. storing images in separate URLs

User enters a site. It contains 1-2 images stored in fastest possible external storage (sidenote: Can I store images as attachment in fastly?).
We have one minified JS file and one minified CSS file.

So we have

  • HTML
  • one minified CSS file
  • one minified JS file
  • 1-2 images

So…
3 requests (HTML, JS, CSS) + 2 requests
5 requests


Questions:

Do we gain a lot of speed when using less HTTP calls (connection estabilish latency etc)?
Is it worth it? Base64 encoding bloats image sizes by 33%. source: http://stackoverflow.com/q/5258057/418518

Which solution/way is gonna work “better” (faster speed)?
Is it possible to do “each” way?

Can I cache whole ‘stuff’ (html, js, css, images)?
Will caching works (good for each customer/visitor) if I have a lot of sites to cache?


PS. If any question looks stupid - sorry we have a very hot discussion in our company and I want to provide all information.


#2

@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.


#3

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.


#4

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.