With this example I want to show how the usage of cookies can undermine effective image caching on websites.
Even though the image filename remains the same, technically, there is a possibility to change the images depending on the cookies the browser has stored.
With Apache, you can point a specific URL to be handled by a PHP script, by adding the following lines in
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^test.png$ /image-test.php [L] </IfModule>
The PHP script
image-test.php then parses the stored cookies and uses the value to modify the image content. In this case, we are getting the image from placehold.it with the text on it, which we can set by appending a URL parameter.
<?php header("Content-type: image/png"); $currentValue = $_COOKIE['my-cookie']; if (!$currentValue) $currentValue = 1; setcookie('my-cookie', $currentValue + 1); echo file_get_contents('https://placehold.it/300x300.png?text='.$currentValue);
Now open the URL
https://www.yourwebsite.com/test.png in your browser. At each refresh you’ll get another image with another value. The filename remains the same and as you can see, the cache headers are set correctly.
The browser doesn’t know whether an image is static or is returned by a dynamic script like the one above. So each time, the cookies on your domain change, the browser will need to fetch the images again and again. Unless you’re images are dynamic and depending on cookies values, you should avoid loading them from the same domain, as the rest of your page.
Here are some very large and absolutely non-cookie-free images
So I am inserting some very large, full-size images from unsplash.com that I uploaded to this domain for demonstration purposes.
Now lets open this page on a 3G network (you can simulate it in Chrome) and see how long they take to load.
Then if you refresh the page, you should see, that the images are delivered instantly – this is because they are cached.
Now if you change a cookie on this domain by , you will see, that the browser doesn’t return the cached images anymore, but fetches them again from the server.