sprite vs individual images - html

Ok - for a web SITE that loads over and over again this is an obvious question. One sprite sheet (that will probably be cached on the users system) and some fancy css background-position trickery, and you're saving yourself a ton of server requests.
But for a web APP, that loads once, and never again. Is a sprite really the way to go. Yes, breaking it up into individual pngs means that many more requests up front, but in the long run, how does this fair?
I'm guessing it depends entirely on the rendering engine and how the memory management works, but it seems like having a 200k sprite sheet duplicated all over the place might be more costly to performance in the long run...

Normally you will use sprite for change states of particular element, e.g. for the button, not for all the images at once. Benefit of using sprites in that case is not just to save a request, but also to make state changes (say on mouse over) instant.

Related

Does a spritesheet use resources for the entire sheet or only what's being loaded from it?

I feel like this is a stupid question since I'm pretty sure the spritesheet uses memory for the entire sheet, but I just wanted to make 100% sure and can't find the answer any where. For a html project I wanted to be 'smart' and make as little http requests as possible, so I created a 2048x2048 image that only has about 150x150 not being used, which is actually great since it can allow me to add other images in the future if I need.
The problem is, after purchasing and configuring a server, I was afraid if a lot of people connected at once, that the server would be using more memory for the bigger spritesheet? I only use 10% of the images in the sprite sheet at any given time, and when they change, the previous ones get replaced. So was it stupid of me to make one big file, will it only use extra memory for no reason? Would the rule of thumb here be, use big sprite sheets for images that are always being loaded, and then split the remainder into smaller sprite sheets that are used only at certain times?
To answer your question, yes the entire sheet is loaded into memory.
However, only once.
Each CSS displays only a small portion of the sprite.
In theory: As you move from page to page that one large image is already in the cache and not requested from the server again. Making the next page load that much faster.
There is much more on caching v/s the number of requests v/s the combined sizes of images that would go into a more complete answer.

Bitmaps Being Cached As Bitmaps

I have a slideshow type portion of an AIR Mobile for iOS I am working on. There are four pages that the user can scroll through. Each page contains a PNG (as large as 1MB, even after compression) loaded in using the Bitmap class and two TextFields. As I am scrolling through them (using a custom scroll framework that works without any issues throughout the app), the app is caching each of the PNG images as a Bitmap as they come onto the screen and unloading them when they leave the screen after a period (most likely the next GC, though it seems to be less random than GC).
The act of caching the PNGs is incredibly slow on iOS, especially when it is happening while another action (such as scrolling) is happening. This produces a ~1 sec delay while scrolling, which is obviously unacceptable. Is there a way to either a) prevent the caching or b) keep them cached longer/indefinitely until the images themselves are eligible for GC?
I've triple checked my code and nothing is set to cacheAsBitmap. Additionally, I've been using Adobe Scout to pinpoint what was causing that momentary freeze and it is definitely from caching the images. I've also eliminated any transforms or scales or filters or anything that might turn cacheAsBitmap on in order to operate and the results remain the same.
It turns out that bitmap caching wasn't really the problem afterall. After much more examination, I found that it was actually PNG decompression. Basically, Flash was decompressing PNGs as they were coming on screen (which is even more expensive than caching), adding those to memory, and undoing the process after they had been off the screen for a period of time, meaning I would have to decompress all over again after that period of time for each image.
To get around this, you simply need to access the BitmapData object in some way. I used getPixel( 0, 0 ) in my constructors and the images were decompressed and loaded into BitmapData permanently upon doing so. It will add a bit of time to the startup, but preloading in this fashion results in better performance.
To avoid this decompressing on the run (on demand) you can instead request flash to decompress it on load. This will increase the load time but improve the perceived performance of the app since a separate thread takes care of the decompressing. This of course means no jitter or skip when the image hits the screen.
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD
var loader:Loader = new Loader();
loader.load(new URLRequest("http://www.adobe.com/myimage.png"), loaderContext);
See: http://help.adobe.com/en_US/as3/dev/WS52621785137562065a8e668112d98c8c4df-8000.html
And
http://www.bytearray.org/?p=2931
Embedded images (via code) are not supposed to be compressed, so this problem shouldn't occur with applications that do so. However, if you are like me, and you use the Flash Pro IDE to import PNGs or other bitmap assets, Flash Pro compresses them as JPG by default, using the setting provided by the image itself.
To fix this and avoid these decompression issues, simply go to your Flash Pro asset library, right click on the image you want to change, click on properties and select "lossless / PNG/GIF" as compression. This will increase largely the load time but you will have the much better perceived performance discussed here. This should be done in addition to implementing the code above, or it will make no difference.
In my experience the frame rate average dropped only by one frame per second, but it's much more consistent without any skips or lags which is essential for games.
Since Flash Player will free the decompressed bitmap memory of a BitmapData, here's a solution if decompression still occurs after this: Keeping Bitmaps Decompressed.

In AS3, how can I dynamically load and unload sequential SWF animations to the stage seamlessly?

I am working on a project that will have the user seeming to fly in 3D from point to point in an architectural model, based on choices. It is a tree-flow, with everything starting from one point and branching out from there, and it only needs to animate in one direction, which makes things easier.
The thing is that the animations from place to place are C4D animations rendered as PNG sequences, and in total they will be VERY large, so I want to package each segment as an individual SWF and load and unload them dynamically as needed.
I expect the first thing to do will be to see if I can have my upstream guy render them as JPG sequences instead... is that a good idea performance-wise? I imagine it will be in terms of bandwidth.
The main question, however, is how I can dynamically load one of these sequences, have it play and stop on its final frame (over which data and choices will display), and then - based on the user's selection - load and play the next animation seamlessly from the first, without endlessly stacking up loaded clips. When the user goes back a level, I only need to jump to the first frame of the animation, but going forward always involves a smooth flight.
I suspect the solution may have to do with adding, say, to the loader by specific names, then as we transition out, load the next one with a specific name, and then unloadChild() and do whatever other kind of garbage collection I need to do to purge from memory entirely. I want to be as cognizant of memory usage and performance as I can, because at certain spots there will be other images and videos loaded on top of the flight animations.
Does anyone have any ideas about this? I'm sure it's a common need, I've just never done it before, and I want to do this as timeline-free as possible.
Thanks in advance for any advice!
Mattynabib

Speeding up the image loading process

How can we speed up the process of loading hundred's of images in as3? it seams to be taking a very long time to load 100's of images.
If you don't have the ability to change the image quality or sizes, then there isn't a lot you can do to speed up such a large load, as you are limited by connection speed and simultaneous browser connections.
You may be benefitted by using a loading manager, like Greensock's LoaderMax. LoaderMax will help make sure you are loading several assets simultaneously - check out the maxConnections parameter.
Also, I suggest not loading everything up front with one preloader. Instead, have placeholders with a spinning loader for each image that then gets replaced by the final image once loaded. This will provide a much smoother user experience and create the illusion of the overall load taking less time.
100s of requests can take quite a long time even if the total size of the images isn't prohibitively large. If you know which images you need in advance, you could embed the images in another swf which you load at runtime.
By the way, what is the reason that you need to load 100s of images right away. Is there any reason you can't load them in the background a little more slowly?
A few suggestions:
Reduce the filesize of your images (obvious but most important).
Don't run all the requests at once - queue the images and load them one at a time (most relevant to least relevant).
There were lots of good advices already. But here a re my 2 cents. One day I had to load about 1000 of really small images. It was taking too long so I used FZip AS3 library. Worked like a charm.
The question does not provide a lot of specifics, so here are some general guidelines.
If the images are large JPEGs, you might be able to sacrifice some quality and recompress the images to make them smaller.
If the images are PNGs and represent, e.g., lots of small, individual tiles for a game, you could try combining many of them into a single image and then parsing them out into images on the client side after loading the image over the network.
Implement download queue, for example simple loader
https://github.com/hydrotik/QueueLoader
Do not load images that
currently out of stage (you can load them in background)
Use texture packer if you have plenty of small images
Optimize pics
quality (i.e. size, type)
Use cache, for instance Local Shared
Object, so for next time you'll get your pics ultimately fast from
LSO.
Is there any way to get thumbnails of the images made? If so, you could use the thumbnails while the larger versions load. Load all the thumbnails first (since they'd load really fast), then load the larger versions in prioritized order.
It sounds like you don't have a lot of control over the images, though. If you don't have any control there, there's very little you can do to speed up the process besides using a loading optimizer as others have suggested.

Why use a sprite sheet rather than individual images?

One thing I have noticed on some sites is that they use one BIIIIIIIG image containing lots of little images, then use CSS background-position to define the coordinates of each image, rather than use individual images.
Here's where I'm at:
Cons for using big sprite sheet
Need to load a large image to just display even one small image
Need to write (or generate) a long stylesheet with a class for each image
Cluttering CSS with lots of class definitions may impact performance
If one image changes (or another is added), cache problems may be encountered both on the image and the CSS associated with it
Requires a <div> with proper styling (display: inline-block; width: 32px; height: 32px; background-image: url('spritesheet.png');) which adds yet another class to the mix.
Many more that I can't remember now I'm typing them.
Pros for using big sprite sheet
... Erm... none yet.
In fact the only thing that comes close to a pro here is that when I cut up the sheet into individual images the resulting folder took up 3Mb on disk (due to each file being <100 bytes and my allocation size being 4k). The actual files themselves come out less than half the size of the sheet and CSS, so even with the overhead of an HTTP request there is a significant space saving.
Basically, my question is: Does anyone have ANY pros for using a big sheet over individual images?
The aim is to reduce HTTP requests. In addition, sometimes the compressed sprite will weigh less than the original images.
Recently I had a website with a lot of transparent gradients (white to trans, grey to trans) and some black and white on transparent images. By putting them all in a sprite and reducing the colors in the png to 8 I could get the sprite to be smaller in filesize than the original images (just... it was about a 0.5% saving). By reducing the number of HTTP requests from 10 to 1 though meant the site loaded faster (if measuring time from first connection to all data transferred).
In that case, a measurable increase was found.
I agree though that it's possible to mess things up and to end up with a larger sprite than needed, especially if you aren't using PNG compression.
Note two years after posting this – if you are using SSL, you should look into SPDY (my note in a further two years will mention HTTP 2.0 instead of SPDY!). SPDY negates the benefits of spriting.
Not much of what you said as Cons really are cons at all.
When you load one large image, it contains only one of the different attributes that an image needs (color table, mime type etc ex: imagine if you're using a progressive jpg format, one spritesheet will allow the image to be scanned once, whereas many will decrease load time significantly) instead of having the same information in 100 different files, it will lessen the filesize in the big picture.
Also there will only be ONE http request (or two, depending on how many spritesheets you have.) but if handled properly, only one per pageload.
If you're using bg images in CSS, then you already have made the css selectors so there is no extra work, just copy/paste the url.
I've never encountered any cache problems with spritesheets that can't be solved by pressing ctrl+F5.
It doesn't require a div with proper styling in any case at all.
This is not an <img> tag replacement method, it's used primarily for bg images. Like for buttons and icon sets.
The pros far outweigh the cons in this method, the proof is that it has been taken up into use by so very many developers. If it were a terrible method, nobody would have picked it up and somebody would have already raised these issues when it was first put into use.
If anyone has more to add, don't be shy :)
Google describes it here. Basically it should reduce page loading time. Every new connection initialization adds some delay. In some cases it can also reduce data transfer size and therefore also reduce page loading time. It is suitable for images that change rarely or all together (themes). Then browser can use cached image and needs to check only one file for changes not every image one by one.
Sprite sheets are a mess. Period. No need to sugar coat it. They present a massive step backwards in design technology, which probably explains why the only people who like using sprite sheets are old school game developers. Sprite sheets only have one redeeming quality, they are a little faster to load. Other than that, they are garbage. Not to mention a nightmare to set up.
In what world is it "acceptable" to have to include 500 lines of code just to run a simple walk cycle. Hopefully some clever guys will come up with a solution as simple as dragging a self contained, alpha-supporting video format such as flv, but that would also run on tablets...
If you feel like writing a massive list about how great sprites are, I can only wonder how boring your design job must be. The bottom line is that if a "tool" is making it harder for you to do things which should be easy, then it's not a good tool. Throw it away.
Yes - number of requests.
Most browsers will only download around 2 resources per domain in parallel, so if you serve up a lot of small images, the user has to wait for for around half that many HTTP request-response cycles. If you use a sprite, that's only one request and one response (albeit a bigger response).
If you have many images, the browser will need to download each and every one of them. Since the browser can only download a limited number of files simultaneously, this will take time. A single image will only tie one download slot allowing the page to render faster.
Additionally, if used in many other pages, the large sprite sheet will already be cached.
this is specially good for a lot of small images, because the browser only has to do an http request for all the images, and not hundreds of them. So you're web loads much faster on the client browser.
the thing is loading speed. Only one http request is quite faster than dozens of them.
Also, it helps keep your CSS cleaner. For instance, I use sprites for buttons (which also means no extra delay for loading the hover state img)
<button type="submit" class="vorige"><span>Vorige</span></button>
button {display: block; width: 162px; height: 47px; background-position: 0 0;}
button:hover {background-position: 0 94px; cursor: pointer;}
button:active {background-position: 0 47px;}
button span {display: none}
.vorige {background-image: url(../img/button/btn_vorige.png);}
.volgende {background-image: url(../img/button/btn_volgende.png);}
.verstuur {background-image: url(../img/button/btn_verstuur.png);}
because of the sprite I can leave out the code for a seperate hover image:
.vorige:hover {background-image: url(../img/button/btn_vorige_active.png);}
.volgende:hover {background-image: url(../img/button/btn_volgende_active.png);}
.verstuur:hover {background-image: url(../img/button/btn_verstuur_active.png);}