Backbone.js, Underscore.js : template images preloading

5.4k views Asked by At

I'm currently finishing a huge Backbone.js application with JQuery, RequireJS and Underscore.

There are many images in my underscore template (lots of .png) and it's a little bit long to append() || prepend() these templates in my current view.

So there is a good way to do what I do ? I'm looking for a library or an example to do preloading on my templates.

2

There are 2 answers

2
nrabinowitz On BEST ANSWER

I don't think you necessarily need a library for this, unless there's one specifically for use with templates. As detailed in these related questions, preloading images is relatively simple:

$("<img />").attr("src", url);

will preload the image at url. It's pretty obvious that you can apply this easily to an array (here using $.each for concise syntax):

function preload(urls) {
    $.each(urls, function(i, url) {
        $("<img />").attr("src", url);
    });
}
preload(['/images/1.png', '/images/2.png', ... ]);

You don't need a library for this. The hard part, in your case, is generating the list of URLs to preload. It's impossible to know the best approach here without understanding your templating system better, but here are a few approaches:

  • If you have your templates available as DOM objects in memory, then you can loop through them using something like $('img').map(function() { return $(this).attr('href') }) to find the URLs. But if you're using Underscore templates in <script> tags and you don't make them into DOM objects until you render the view, then this is unlikely to work - it's going to be a pain and somewhat processor-intensive to render them with dummy data just for the purpose of extracting URLs.

  • If you use a build system like Ant, and if your templates are fairly separate from your other code (e.g. each template in a separate file), then you might consider using regex to parse the templates for URLs and then sticking them into an array in a Javascript file, which you can use for input to your preloader. This is a pretty complicated build task, but it's probably the best option from a performance standpoint, as all the template parsing happens at build time, not at run time.

  • Another build system approach, probably simpler, would be to put all images you want to preload into a given directory, and then put every file under that directory into the Javascript array. This is probably the easiest approach with Ant, though it might require you to revise your directory structure for images.

  • You can always make your array of URLs by hand, but it will be a pain to keep it up to date with a complex set of templates.

  • If you have a complex app and you want to only preload certain images at any given time, you'll probably need to identify those images by hand, and then call preload(upcomingImages) at the appropriate time for the appropriate set of images.

0
LoG On

If you need a more granular control you can use the DOM's Image object. Like:

var img = new Image();

img.src = 'image.png';

img.load = function () {
  console.log('image.png is fully loaded');
}

You will need to queue the image urls and at least one callback.

a simple worker would look like:

function worker (url, callback) {
  var img = new Image();
  img.src = url;
  img.load = callback;
}