Include images in css - css

Looking at the source of a website today I came across something that surprised me. They had the images included in the css file (see http://static.a.gs-cdn.net/webincludes/css/production-uri.css?20120521.1)
This surprised me, surely loading one large file with all the images embedded would take longer on a modern browser (ie chrome fires off lots a simultaneous requests for the content it needs) and make it harder to debug any css issues. Is that correct and are there any advantages to this approach?

There's nothing really wrong with including images in CSS, although it may be more efficient to use CSS sprites.
It makes sense to use CSS sprites for UI elements (but not content elements) because it reduces the number of HTTP requests.

This is a good article detailing a few of the pros and cons of such an approach.
Pros:
The biggest reason: it saves HTTP Requests. Other than pure document size, this is the #1 factor concerning how fast a page loads. Less = better.
Cons:
It's hard to maintain site with embedded data URIs for everything. It's easier to just update an image and replace it.
You should only use this in documents that are heavily cached, like your CSS should be. Having a CSS file that is 300k instead of 50k is fine if it saves 6 HTTP requests, but only if that CSS file is cached just as well as those images would be.
Personally, I never use it. It saves on HTTP requests, but bloats your CSS with things that are, in my opinion, not appropriate. For a clean separation of concerns, images should be just that - images.
Plus, you'll have a harder time caching all the resources - if you make one change to your CSS, that's all the image data getting re-downloaded for no reason.

Related

What are the implications of a cached CSS file?

Specifically, does the browser cache only the text content of the stylesheet — so it doesn't have to fetch it again from the network — or does it also cache an internal representation it has of the contained CSS rules after parsing, so neither fetching nor parsing of a cached file is necessary?
If only the text content is cached, what are the benefits of caching a stylesheet over inlining it (where it cannot be cached)?
Caching is aimed at reducing load time by replacing the typically slow network download with the typically fast local file reading. As such, is a generic solution (you can cache any kind of asset, from HTML to CSS, JavaScript, PDFs, Excel...) and it can accomplish great time savings (normally seconds, even minutes for really slow networks). It also plays well with dynamic HTML.
What you propose is a very specific caching solution for a very specific data set (the nodes of an HTML document together with the CSS rules that apply to them) that typically needs milliseconds to process and can be continually changing thanks to JavaScript. It looks really difficult to implement, it'll be confusing for dynamic sites (when a page loads, everybody expects to get the initial HTML state, not whatever you were doing last time) and there's hardly any benefit on it. I'm not aware of any browser that has even tried it. There're certainly JIT compilers for JavaScript code, but nothing remotely similar to this.
If only the text content is cached, what are the benefits of caching a
stylesheet over inlining it (where it cannot be cached)?
I'd say cache itself is a valid benefit, isn't it? Generating inline CSS means more work for the webmaster (you either need to write server-side code that injects CSS files or enjoy the maintenance mess of not even having them). It also increases the size of HTML documents.

Inline base64-encoded images or HTTP request?

There are at least two ways to use an image in CSS:
with an HTTP request;
url(/path/to/image.png)
with a data URL.
url(data:image/png;base64,BASE64_ENCODED_DATA_HERE)
But I was wondering, as base64-encoded data takes 33% more space, therefore 33% more time to load, is it worth it, or should I just make an HTTP request--using a sprite if there're several images?
A separate request is almost always preferable because with data: URIs,
it doesn't work in older IEs and is limited to 32k in IE8
it can be argued that it goes against separation of styling and content
Style sheet files get blown up, which may cause trouble if the browser's developers never expected CSS files to reach these kinds of sizes
I would use it only when there is no other choice.
The web server should take care of the 33 % more space by GZIP-ing all text files so that should not be that big of a problem. This together with reducing the number of HTTP requests (which is very important performance-wise) makes the method worthwhile. Also, the images are still cached but now in the CSS file instead of in separate files.
Preferably the embedding should be done with a build script that inserts the data URIs. That way we don't have to care about large chunks of base64-encoded data when editing the CSS files. Also, remember to have a good solution if images occur more than one time in the file, e.g. re-writing the CSS rules. We don't want the file to be larger than necessary.
There are problems with IE though. IE<=7 can't handle data URIs at all and IE8 can't handle them for larger URIs than 32K. The latter could be solved by simply not embedding too large images (maybe you shouldn't anyway). Regarding IE<=7 the problem can be solved by using MHTML instead and specifying different CSS files for different browsers using IE conditional comments.
Here is a good blog post about embedding images in CSS and how to fix the problems for IE: http://blog.meebo.com/?p=2320
Personally, I would always go with a separate request. I've had trouble in the past with Internet Explorer and data:url images.
It seems IE8 limits url length to 32KB, which is often not enough for images.
Wikipedia on Browser Support

single stylesheet or numerous

I don't know much about speeds and all of that, so I'm not sure if a huge stylesheet would show significant changes in the loading of the page or not. To keep it simple, I want to use a stylesheet that covers all areas of the website using IDs, like #forum div.menu or #game div.menu. Knowing that this would make the stylesheet large, I'm uneasy about it being too much. Could someone provide insight on the significance of the size of a stylesheet and perhaps some specs?
If your users are going to be using all those styles anyway, it is usually better to serve it in one stylesheet because it reduces the HTTP requests and allows the browser to cache it all. However, if you have a lot of CSS for only one page that is not commonly visited for your users (and it is enough that including it in the global stylesheet adds a bunch of weight and would add a substantial amount to the file), it may be better to put it in a separate file.
Bigger stylesheets are better than smaller, multiple stylesheets when trying for speed. HTTP requests are one of the main reasons of slowing your webpage down. Its the same with images. One big image is far better than a lot of littler ones. Here is a good link for reducing your http requests: http://www.dailyblogtips.com/speed-up-your-site-reduce-the-http-requests/.
You may find this Yahoo Developer Network article very useful.
It has a number of sections regarding optimization of CSS
for your site.
"Best Practices for Speeding Up Your Web Site"
http://developer.yahoo.com/performance/rules.html

How can I create CSS sprites from images stored in the database?

I have an ASHX handler that I am using to display images that are stored in a database. I display the images as thumbnails and then full size if the user mouses over them.
How can I combine the images at runtime to produce CSS sprites for use in this situation?
If it can be done does anyone have suggestions on where to start?
UPATE
It seems like most people are saying this is not a good situation to use sprites in. I'm new to the sprite concept so please bear with me.
If I am going to be loading 30 thumbnails on a page from my database everytime why would it not make sense to pass them from the server to the client as one large image instead of passing 30 individual images? Wouldn't this be faster? Isn't this the purpose of CSS Sprites?
As far as the browser is concerned, an HTTP resource is an HTTP resource and it is irrelevant if the server produced it by reading a file from a hard disk, taking data out of a database, or spewing the content of a random number generator through an algorithm that would output valid PNG data.
You just need to generate your images from the data as normal.
That said, since the images are content, CSS would be an inappropriate tool to include them in the document. You should use an <img> element.
You have a couple options.
Your handler can combine the images on the fly that it gets from the database and send the whole thing down to the browser.
OR (and I like this one better)
You create the merged image at the time the images are uploaded to your site.
The second is better as the conversion only has to happen once and therefore means that you only have to spend those resources once. It does mean you are essentially storing 2 copies of the image, but that's fine.
UPDATE
I believe I misinterpreted what you were trying to do. I thought you were trying to combine the thumbnail with the full blown image. Instead, you appear to be really asking how to combine all of the thumbnail images.
In that case, it's even more of a bad idea. As David Dorward stated CSS is used to control layout. You're talking about content. However, the semantic issue aside, in the event you want to make tweaks to the layout your going to have to modify your code which creates the sprites to begin with. What if you decide to do 35 images? Or, change that to do 18?
By going the sprite route your pretty well screwed by being forced to modify code for any layout change which is NOT good style.
To cover that last question: wouldn't it be faster? Probably not. Under this scenario you would have to create the sprite on the fly, which introduces server overhead, which slows everything down. At most it might be a wash in the delivery time. At worst, you incur a large server and development performance negative impact.
Check out http://www.RequestReduce.com. It not only creates the sprite file automatically, but it does it on the fly through an HttpModule along with merging and minifying all CSS. It lso optimizes the sprite image using quantization and lossless compression and it handles the serving of the generated files using ETags and Expires headers to ensure optimal browser caching. The setup is trivial involving just a simple web.config change. See my blog post about its adoption by the Microsoft Visual Studio and MSDN Samples gallery.
I completely agree with David. Just a quick note regarding David's last point: That's only if the images are content. However, if they were part of the layout, then CSS would be appropriate.
That said, with this use case, sprites aren't a good choice. One of the purposes of thumbnails is to cut down loading time, which a sprite would make worse for a gallery. A better pattern might be using a lightbox or something similar with two images rather than one, with the larger being requested on demand.
Sprites are not a good solution here.
To answer your update, sprites are ideal for many small images, where the overhead of a new HTTP request outweighs the few bytes being sent for a small png or gif (e.g. 16x16 icons, etc). For larger images the time of the HTTP request becomes less important overall as the download time increases.
Packing images into a sprite also means that they will execute one longer request and other requests will have to queue behind it. If the important thing is to get the thumbnails showing quickly, then make sure those get loaded first before starting to load any larger views of the same images.
Any larger files that don't display at the initial page load should be late-loaded (window.onload) or lazy-loaded (as needed by click or hover actions).

Should I aim for fewer HTTP requests or more cacheable CSS files?

We're being told that fewer HTTP requests per page load is a Good Thing. The extreme form of that for CSS would be to have a single, unique CSS file per page, with any shared site-wide styles duplicated in each file.
But there's a trade off there. If you have separate shared global CSS files, they can be cached once when the front page is loaded and then re-used on multiple pages, thereby reducing the necessary size of the page-specific CSS files.
So which is better in real-world practice? Shorter CSS files through multiple discrete CSS files that are cacheable, or fewer HTTP requests through fewer-but-larger CSS files?
Your first port of call is using YSlow or Google Speed to figure out what is going slowest on your site. Sometimes a badly compressed (large) image or two can be slowing the entire thing down. You are told to reduce HTTP requests because each request has a setup cost associated with it but if taken to the extreme can lead to worse performance. In your case having a CSS file for each page is bad form as it means it is harder for browsers to cache.
Taking one method to the extreme is bad practice and you should attempt to approach this problem from a wide angle such as:
Properly compress images or use CSS sprites (reduces HTTP requests)
Implement proper web caching using Expres, ETag etc (so clients don't have to rerequest everything)
Optimise your CSS and Javascript files using YUI or another similar tool
Improve your CSS / javascript code for performance. Certain CSS selectors can lead to the browser taking longer to render a page
Replace images with pure CSS where possible i.e. background colors etc.
Use GZip compression on any text output i.e. html, css, js
If in doubt, look at the source page for the Google home page. They optimise that page heavily and it will give you good clues on what to do.
I would go for combining all CSS into one single CSS file. Even if you have some redundant styles that won't apply to all pages, after compressing it with Gzip the size should be small enough. And after the browser has cached it, the size no longer matters. Just insert all CSS into one file. However, you have one problem: the styles change for different pages. You have to take another route. You could do, for example, something like:
index.html
<div class="navigation_index"></div>
about.html
<div class="navigation_about"></div>
And then share the similar styles along with the navigation classes like:
.navigation_about, .navigation_index {
color: #000;
}
and specify different options in separate styles:
.navigation_about {
font: sans-serif,
}
.navigation_index {
font: serif,
}
Browsers will cache the css files what ever its big or small, so i prefer making bigger css files with fewer requests.
But this is not a rule, i just try to do that as i can.
well crap, i think theoretically it depends on the site type. If people are going to hit the pages of the site one time, and one time only and theres a lot of pages and such, then having the broken up css files ends up working out better on a graph. Versus a site or web app where everything is getting hit constantly or often enough anyway, then having specialized/compiled css for each page might have a bigger hit at first (on a graph anyway), but then gets cached and you win in the long run b/c of fewer http requests. And then theres some overlap-age there somewhere in the nether regions of mass css hysteria.
Now get away from the graphs and look at your average site, it probably doesn't matter unless you taking on some really serious traffic. But overall ima vote for the latter here.

Resources