Categories

Optimize cached images

Posted on: April 25, 2016 by Dimitar Ivanov

Caching rocks!

Caching images is a well-known practice for website optimization. After the first visit, the browser downloads images and stores them in the cache. When the page is visited again, images are taken out from the cache. Therefore, the browser makes fewer HTTP requests. So page loads faster.

Why to avoid query string

When an image is changed or replaced, we have to inform the browser to download the new image. So we have to change the filename. Some developers append a random string or file version after the filename. That works in most cases. Note that some proxies refuse to cache files with query string. To overcome this drawback use a file modification time in a filename. Let's see how in details.

Optimize Cached Images in 5 steps

  1. Set cache policy for image requests:
    <IfModule mod_headers.c>
      <FilesMatch "\.(jpe?g|png|gif|webp)$">
        Header set Cache-Control "public, no-transform, max-age=31536000"
      </FilesMatch>
    </IfModule>
    
  2. Set a far-future expires header:
    <IfModule mod_expires.c>
      ExpiresActive On
      ExpiresDefault "access plus 10 days"
      ExpiresByType image/gif "access plus 1 year"
      ExpiresByType image/png "access plus 1 year"
      ExpiresByType image/jpeg "access plus 1 year"
      ExpiresByType image/webp "access plus 1 year"
    </IfModule>
    
  3. Use a file modification time in filename
    <?php 
    function getImage($filename) {
        if (!file_exists($filename)) {
            return FALSE;
        }
        # Gets file extension
        $arr = explode('.', $filename);
        $extension = strtolower($arr[count($arr) - 1]);
    
        # Gets file modification time
        clearstatcache();
        $time = filemtime($filename);
    
        $position = strripos($filename, '.'.$extension);
    
        return sprintf('%s-%s.%s', substr($filename, 0, $position), $time, $extension);
    }
    ?>
    
    <img src="<?php echo getImage('image.png'); ?>">
    
    <!-- 
        The above code will produce:
        <img src="image-1461525283.png">
    -->
    
  4. Rewrite new filename to match the file on server
    <IfModule mod_rewrite.c>
      RewriteRule ^(.*)-\d{10}\.(jpe?g|png|gif|webp)$ $1.$2 [L,NC]
    </IfModule>
    
  5. Remove etag header
    <IfModule mod_headers.c>
      Header unset ETag
    </IfModule>
    FileETag none
    

Conclusion

Using a htaccess to rewrite the image filename is a bit slower than serving a file from disk. However, the overall improvement of speed is much bigger.

See also
Share this post

If you have questions about image optimization, please leave a comment below. Thanks so much for reading!


0 Comments

Comments are closed