I’ve been putting together a demo the past couple of days for a sales pitch that our sales guys will be going on in a couple of weeks. The demo will be wrapped in Cordova and shown on an iPad Pro and will have lots of full-screen (or at minimum near-full-screen) background images. As you might imagine, those images can be quite large in file size. I’ve compressed them to a reasonable amount but fearing that my view rendering might be less than perfect I’ve decided to write a caching mechanism for them.
_cache
First I’ve set up the following variables; one that lists all the images that I want to cache, the next is a counter that will be incremented with each image load.

// add all images to be cached in this array
var _imagesToCache = ['home_bg.jpg','interstate_bg.jpg'];

// incremented by onload events. when this equals (_imagesToChache.length -1) we know all large assets have been loaded
var _cachedImages = 0; 

Here’s the class I wrote that will do the heavy lifting:

/**
 * This will cache an image
 * @private
 * @param {string} path the path to the image to be cached
 */
function CacheImage(){
   var img = new Image();
   img.onload = function(){
       _cachedImages++;
   };
   this.cache = function(path){
      img.src = 'css/images/' + path;
   };
}

Next I iterate through the image array and start the caching process:

/**
 * loads large assets, (i.e., images) in an attempt to cache them and speed up view render time
 * @method
 * @type {Function}
 * @name airstream.model.loadLargeAssets
 */
ns.loadLargeAssets = function(){
   var i, len = _imagesToCache.length;
   for (i=0;i

When the app clears the DOM Ready and Device Ready events I then start caching my templates and images. I poll the status of both with a setTimeout within the following function:

/**
 * Recursive function that checks for the successful caching of templates and images.
 * @method
 * @type {Function}
 * @name airstream.model.loadTemplates()
 * @param {}
 * @return {} Returns nothing
 */
ns.checkForCompleteLoad = function(){
   // this is for my template caching, not related to image caching stuff
   var loaded = true;
   for (var p in _templates){
      if (!_templates[p]){
         loaded = false;
      }
   }
   // This next line deals with looking to see if the images have been loaded 
   if (!loaded || _cachedImages !== _imagesToCache.length){ // check the image cache counter
      window.setTimeout(airstream.model.checkForCompleteLoad,100); // try again in 100ms
   } else {
      console.log('Images Cached: ' + _cachedImages);
      airstream.view.renderHomeView();
   }
};

In reviewing this I could easily remove the polling and instead do the "complete load check" in each template or image-caching instance where once they have completed their tasks they check the counters vs the length of the template and image arrays. At that point they could decided if they were the last ones to load and then fire the rendering of the initial view if true.

Anyway, the above does the job for now. I'll find time to refine things when there's time to be had.