Should I embed images as data/base64 in CSS or HTML
To reduce the number requests on the server I have embedded some images (PNG & SVG) as BASE64 directly into the css. (Its automated in the build process)
like this:
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAFWHRTb2Z0d2FyZQBBZG etc...);
Is this a good practice? Are there some reasons to avoid this? Are there some major browser that don't have data url support?
Bonus question: Does it make sense to do this for the CSS & JS开发者_如何学C also?
Is this a good practice? Are there some reasons to avoid this?
It's a good practice usually only for very small CSS images that are going to be used together (like CSS sprites) when IE compatibility doesn't matter, and saving the request is more important than cacheability.
It has a number of notable downsides:
Doesn't work at all in IE6 and 7.
Works for resources only up to 32k in size in IE8. This is the limit that applies after base64 encoding. In other words, no longer than 32768 characters.
It saves a request, but bloats the HTML page instead! And makes images uncacheable. They get loaded every time the containing page or style sheet get loaded.
Base64 encoding bloats image sizes by 33%.
If served in a gzipped resource,
data:
images are almost certainly going to be a terrible strain on the server's resources! Images are traditionally very CPU intensive to compress, with very little reduction in size.
Common answers here seems to suggest this is not needed, for a set of legit reasons. However, all of these seems to neglect modern apps behavior and build process.
It's not impossible (and actually quite easy) to design a simple process that will walk through a folder images and will generate a single CSS with all the images of this folder.
This css will be fully cached and will dramatically reduce round trips to the server, which is as correctly suggest by @MemeDeveloper one of the biggest performance hits.
Sure, It's hack. no doubt. same as sprites are a hack. In perfect world this will not be needed, until then, it's a possible practice if what you need to fix is:
- Page with multiple images that are not easily "spritable".
- Round trip to servers are an actual bottleneck (think mobile).
- speed (to the milliseconds level) is really that important for your use case.
- You don't care (as you should, if you want the web to go forward) about IE5 and IE6.
my view.
It's not a good practice. Some browsers are not supporting data URIs (e.g. IE 6 and 7) or support is limited (e.g. 32KB for IE8).
See also this Wikipedia article for complete details on the Data URI disadvantages:
- Data URI scheme
Disadvantages
- Data URIs are not separately cached from their containing documents (e.g. CSS or HTML files) so data is downloaded every time the containing documents are redownloaded.
- Content must be re-encoded and re-embedded every time a change is made.
- Internet Explorer through version 7 (approximately 15% of the market as of January 2011), lacks support.
- Internet Explorer 8 limits data URIs to a maximum length of 32 KB.
- Data is included as a simple stream, and many processing environments (such as web browsers) may not support using containers (such as
multipart/alternative
ormessage/rfc822
) to provide greater complexity such as metadata, data compression, or content negotiation.- Base64-encoded data URIs are 1/3 larger in size than their binary equivalent. (However, this overhead is reduced to 2-3% if the HTTP server compresses the response using gzip)
- Data URIs make it more difficult for security software to filter content.
I was using data-uri's for about a month, and Ive just stopped using them because they made my stylesheets absolutely enormous.
Data-uri's do work in IE6/7 (you just need to serve an mhtml file to those browsers).
The one benefit I got from using data-uri's was that my background images rendered as soon as the stylesheet was downloaded, as opposed to the gradual loading we see otherwise
It's nice that we have this technique available, but I won't be using it too much in the future. I do recommend trying it out though, just so you know for yourself
I'd more inclined to use CSS Sprites to combine the images and save on requests. I've never tried the base64 technique but it apparently doesn't work in IE6 and IE7. Also means that if any images changes then you have to redeliver the whole lost, unless you have multiple CSS files, of course.
I have no idea about general best practices but I for one would not like to see that kind of thing if I could help it. :)
Web browsers and servers have a whole load of caching stuff built in so I would have thought your best bet was to just get your server to tell the client to cache image files. Unless you are having loads of really small images on a page then I wouldn't have thought the overhead of multiple requests was that big a deal. Browsers generally will use the same connection to request lots of files so there are no new network connections being established so unless the volume of traffic through HTTP headers is significant compared to the size of the image files I wouldn't worry about multiple requests too much.
Are there reasons why you think there are too many requests going to the server at the moment?
I would suggest it for tiny images that are used very often, for example common icons of a web application.
- Tiny, because the Base64 encoding increases the size
- Often used, because this justifies the longer initial load time
Of course support problems with older browsers have to be kept in mind. Also it might be a good idea to use the capability of a framework to automatically inline the images a data urls such as GWT's ClientBundle or at least use CSS classes instead of adding it to the element's style directly.
More information are gathered here: http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/
精彩评论