In general the images you are loading through the browser is kept in a memory cache. Unless there is very little memory the images typically stays there, otherwise the browser will have to purge the memory cache (not related to GC which deals with unreferenced objects), or part of it, and reload the image(s) from either the local disk cache (if enabled) or again from server if for some reason the local disk cache is disabled or full causing previous loaded images to be deleted from it (note: this is browser dependent and this describes the method in a simplified way - some browsers have advanced loading systems able to handle thousands of images in a single page such as the recent Firefox).
In any case you won't need to think about setting src
again if that is what you mean. The browser will take care of all the loading for you internally. You just need to make sure you handle the first asynchronous loading as you do in the example. If the image has a reference it will be available. That being said you may have to deal with peculiar browsers which do some wacky stuff in this regard (hrm..IE..he).
200 kb says really very little about an image. It could be uncompressed PNG as well as heavily compressed JPEG. What matter is the pixel dimension. As all images loaded in the browser are converted to uncompressed RGBA the memory usage will be (minimum) width x height x 4
. Then there is temporary memory used for it and most likely other buffers as well depending on scenario and method of painting etc. (by the browser). But also have in mind more advanced browsers which can handle as said thousands of images in a single page so this may not become such as huge problem after all.
Image loading itself has nothing to do with the canvas element though. What you draw onto canvas is independent on this whether it is an image or a shape that you draw. Canvas do not lock/reference the image in any way except from actually drawing it - after that the image is forgotten from the canvas point of view, but the image will still be available as described in the beginning as long as it has a reference to it. Images are usually resources associated with the DOM and in some cases JavaScript, ie. as typed arrays etc.
Canvas is, as you touch upon, passive so it does not know from where the pixels came from or in what area, order etc. the pixel was drawn in. It just keeps the final resulting pixel blend from these various operations. All tracking and mechanisms needs to be done outside canvas with custom objects etc.
3000 - 6000+ images sounds a bit much for a browser application (IMO) but if there is memory enough on the system it won't be a problem per se - just don't expect the user to have the same specs (or fast connection) as your developer machine so be prepared to handle errors (as always) and inpatient users...
You should probably consider caching compositions of these images and/or make a loading/reference system that loads the images on demand - how efficient this will be depends on the user configuration (cache size, cache enabled, memory, internet connection etc.) but how to do this is beyond the scope here.
Also, if I may, you could use an image loader as my YAIL bulk image loader which at least takes care of the initial image loading.
To avoid GC removes your images you need to make sure you always keep a reference to the image(s). In your example code some of your images' references will run out of scope and GC may remove the image from memory.
$.fn.reBuildScooter = function(canvas, ctx, scoPath, supPath, sustPath, colourPath) {
/// this is only available inside reBuildScooter and to the children scopes
var sco = new Image();
sco.onload = function() {
/// sup is only available inside this function and to children
/// when function returns sup will be lost when sco.onload.. returns
var sup = new Image();
sup.onload = function() {
/// same as with sup...
var sust = new Image();
sust.onload = function() {
ctx.clearRect ( 0 , 0 , canvas.width , canvas.height );
...
In order to keep a reference to the images you either have to move them to global scope or to "root" inside an instance of the object - for example:
$.fn.reBuildScooter = function(canvas, ctx, scoPath, supPath, sustPath, colourPath) {
var sup;
var sust;
var sco = new Image();
sco.onload = function() {
/// sup is now available within the reBuildScooter
sup = new Image();
sup.onload = function() {
/// same as with sup...
sust = new Image();
sust.onload = function() {
ctx.clearRect ( 0 , 0 , canvas.width , canvas.height );
...
As long as your reBuildScooter
object lives (which it probably will in this case) the variables inside will also be kept alive and GC won't collect. But the browser can still purge the memory cache but it will be for the most part be transparent (for lower spec'ed systems there may be reduced performance).
Hope this gives some input.