Several hundred CSS sprites in a file is pushing it. It would probably be a better idea to keep it to a ~20 or so per file. Plus, if I remember playing Civ, you can lazy load the suckers -- when you start out all you can see is a lot of black, a settler, and maybe 6 or so unique sets of tiles, plus the game interface. You don't need to block on waiting for the battleship icon for quite a while.
Civ also has some features which make it very easy to cheat creatively regarding logic for loading those things. You can guarantee, for example, that no Riflemen will show up anywhere on the map until someone has discovered Gunpowder. Thus, if someone discoverse Gunpowder, you send everyone an <img src=".../gunpowder_units.gif" style="display: hidden;" /> and you'll have the Riflemen sprite available instantly once someone actually constructs one. (Edit: There are, of course, security issues associated with that example.)
Internet Explorer has a limitation where only one image can be downloaded at a time
Really? Are they sure they don't mean "IE only downloads two resources in parallel from any particular domain, like suggested in the HTTP spec"? This has a fairly simple solution, familiar to anyone who has read the YSlow stuff: create a few subdomains to alias your HTTP server, load images from a few of them at a time. I do it for my website, works like a treat.
I would sprite each set of tiles, based on the dimensions. So you'd have one image for all the terrain tiles, one for all the terrain decorations (grains/shields/whales/fish/game/etc.), one for all the improvements, one for city styles at each game era, one for units (again based on game era - put your phalanxes/warriors/settlers in one sprite, your battleships/airplanes/carriers in another), etc.
This also avoids some nasty binpacking problems around combining sprites of different sizes.
When the game starts up, you only need to preload the terrain, terrain decoration, and initial unit sprites - that's probably a couple dozen, no more than you'd need to draw the page as an image. Less, actually, since you can re-use your terrain sprites.
You should then be preloading the other sprites as the game goes on. If the user isn't doing anything, use that network connection to download the next spriteset the game will need.
So you are suggesting to stop using the HTML canvas element, and instead use Javascript to render tiles which are clipped using CSS from one large image?
I think you could do both. Position 96x48px divs with css sprites over the canvas element to draw the images. I think this would be a performance win too, because browsers are already very good at drawing things like css sprites (although I don't know how well it combines with the canvas element).
What would you end up drawing on the canvas, if the images are drawn with sprites? I can't think of anything else in Civilization that gets drawn, other than text for city names (which should probably be done as absolutely-positioned spans).
You can, but it's quite a bit slower. IIRC I benchmarked drawing a 32x32 image on canvas at about 15ms, while setting the top and left properties of an img tag or div with a background image was under 1 ms. The absolute numbers mean nothing (it was on an old laptop under Linux), but the ratios indicate at least an order of magnitude different in performance.
A somewhat related idea: Shouldn't it be possible to implement "canvas sprites" (no CSS involved) by downloading a large image, carving it on the client side, and drawing the sprites into a canvas?
That should cut down on both latency and issues with IE only downloading one image at a time.