0

I have a Three.JS powered WebGL example found at

http://jsfiddle.net/dja1/7xwrqnen/

 material.map = THREE.ImageUtils.loadTexture('/images/earthmap2k.jpg');

If you use Chrome, you will see that when the large image is requested the caching for this image is correctly set to 'max-age=1296000'. If you 'Play' the JSFiddle again the image is not downloaded again - as expected.

However if you repeat in IE 11 then the image is always downloaded. It appears to complete ignore the caching.

For a large file this can be a real problem since when you click on a hyperlink that goes to a different page yet displays the same type of animation then the image needs to be downloaded again making for a poor user experience.

Does WebGl just ignore image caching in IE 11? What would a work around be?

Thanks in advance. Dave A

DJA
  • 661
  • 1
  • 9
  • 25
  • You're using r54, which is way ancient. Please use a much more recent version of three.js (you'll have to manually add it to the fiddle). Also, checking the headers that are being sent it sends 'Cache-Control: no-cache;' so not using the cache is entirely valid. A newer version of three.js might behave differently here. – Leeft Oct 28 '15 at 12:43
  • Thanks. I have updated the jsfiddle to the most recent version of three.js but it has made no difference. http://jsfiddle.net/dja1/c3hcavnj/2/ I guess you are referring to the HTTP header "Pragma: no-cache" ? How do I get three.js to use something different? – DJA Oct 28 '15 at 13:10
  • Three.js doesn't send headers. The web server serving the image sends them. If you want different cache headers you need to configure your server. – gman Oct 29 '15 at 03:07

2 Answers2

0

Looking through the source code, you'd end up at https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js where you can see it does:

var image = document.createElement( 'img' );

Using image elements like that doesn't offer any control over caching. In that file you can also see that it does cache internally, but that doesn't help across reloads. So, in short, what you're seeing here will be some IE11 specific behaviour where it decides to reload the image each time.

Leeft
  • 3,827
  • 1
  • 17
  • 25
  • Other than "don't use IE", can you think of any work arounds? Three.js could really benefit being changed in this area. – DJA Oct 28 '15 at 22:32
  • Sending different headers on the server might do the job. Other than that, there are limits to what you can do in a browser to load an image, it's entirely up to the browser without control from JavaScript. It's not three.js's fault ... see .e.g. http://stackoverflow.com/questions/5017454/make-ie-to-cache-resources-but-always-revalidate (that's more about preventing caching though). – Leeft Oct 28 '15 at 23:07
  • What you have said is technically incorrect. See this jsfiddle http://jsfiddle.net/dja1/zypvfx2n/ that does a createElement('img') and does full caching. There is more to this story. I will research further and post back with my findings. – DJA Oct 29 '15 at 11:32
  • It's not using the same image (or even the same server) and while I don't have the time right now to compare the differences in these server responses, I'm pretty sure there will be significant differences there, resulting in IE11 caching one and not the other. – Leeft Oct 29 '15 at 13:19
0

I have now researched this topic and can provide some insights.

In order to get caching to happen as described you need to have three things in place;

  1. The server needs to send a Cache-Control max-age (or similar) in the response to the request for the web page.
HTTP/1.1 200 OK
Cache-Control: max-age=1296000
Content-Type: text/html
  1. The server needs to send a Cache-Control max-age (or similar) in the response to the request for the image
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=1296000
Content-Type: image/jpeg
  1. This line must be commented out from the javascript.
THREE.ImageUtils.crossOrigin = 'anonymous';

This last line is the message to Three JS (and WebGL) to allow the use of images from other web servers. In my case I wanted to use a CDN to serve the large image. So this means that CDNs are effectively precluded from being used with Three JS; you can use them, its just the image will be re-downloaded every time the page is requested which defeats the purpose of the caching.

The difficultly in demonstrating this solution with jsFiddle is that it does not issue the 'cache-control' when the jsFiddle page is requested (and rightly so) so it will always re-download the image when running in jsFiddle.

DJA
  • 661
  • 1
  • 9
  • 25