views:

36

answers:

2

I'm using javascript to dynamically load any of a series of images into a single img tag, based on user interaction:

function reassignImage(newSource)
{
   img.src = newSource;
}

This works great, except that I when I inspect it with Chrome developer tools, I see that even if I reload an image I've already loaded, it makes another http call AND grows the total Images Size graph.

This seems like the worst of both worlds. I would want either:

  1. To load from cache if the image were the same.
  2. To reload each image everytime, but then not grow the cache.

How would I achieve either scenario?

Thanks! Yarin

+1  A: 

This will pre-load an image so that the browser can display it immediately when you actually set the src of an img tag. I speculate that pre-loading an image like this will ensure it's in the cache so it won't reload, though I haven't tested it.

var myImg = new Image(25, 25);
myImg.src = "/foobar.png";

In other words, this should now hopefully only download two images

function reassignImage(newSource) {
    var myImg = new Image(25, 25);
    myImg.src = newSource;
    img.src = newSource;
}

reassignImage("first.png");
reassignImage("second.png");
reassignImage("first.png");

Edit

I was doing it wrong. Try creating a new Image() for every new file the user loads. Swap these image elements in and out of the dom.

<html>
  <head>
    <script>
    var imageElements = {};
    function reassignImage(newSource) {
      if (typeof imageElements[newSource] == "undefined") {
        imageElements[newSource] = new Image();
        imageElements[newSource].src = newSource;
      }
      var container = document.getElementById("imageContainer");
      container.innerHTML = '';
      container.appendChild(imageElements[newSource]);
    }
    </script>
  </head>
  <body>
    <div id="imageContainer"></div>
  </body>
</html>
Dave Aaron Smith
@Dave- not sure I follow. Are you saying that by creating the actual Image tag dynamically, it effects how images are cached? And the second part of your example is unclear- why do you assign the newSource to two diff img components?
Yarin
@Yarin `new Image` doesn't create an image _tag_ it creates an image _object_. This is the party approved way to pre-load images. I'm guessing that using these image objects will affect how the image files are cached, yes. `myImg.src = newSource` assigns the `src` of an image _object_ while `img.src = newSource` assigns the `src` of your image _tag_.
Dave Aaron Smith
@Dave- OK Interesting I hadn't realized the concept of Image objects. However, still confused by the example- what do we DO with the Image object you created- shouldn't we assign it to img.src?
Yarin
@Yarin, on second thought, I think you're right. `new Image` is the same type as document.getElementById("myImageId"). I suspect my answer is useless. Sorry about that!
Dave Aaron Smith
Actually that gives me another idea. Hold on a second, I'll put it together and edit my answer.
Dave Aaron Smith
YES! new version works great- thanks Dave!
Yarin
+2  A: 

What's the cache-control header set to in the http response for the image? (Chrome developer tools will show you). If it's not set to be cacheable, it will get refetched.

Nik
@Nik- good point here- so a follow up question is how do you control cache-control headers off of something like Amazon Cloudfront or other CDNs?
Yarin
Not sure about cloudfront, but Amazon S3 allows you to set any header you like when you upload - I would imagine CDNs do too.
Nik