Web Performance - Cache

Web Performance - Cache

README

Most web pages include resources that change infrequently, such as CSS files, image files, JavaScript files, and so on. These resources take time to download over the network, which increases the time it takes to load a web page. HTTP caching allows these resources to be saved, or cached, by a browser or proxy. Once a resource is cached, a browser or proxy can refer to the locally cached copy instead of having to download it again on subsequent visits to the web page. Thus caching is a double win: you reduce round-trip time by eliminating numerous HTTP requests for the required resources, and you substantially reduce the total payload size of the responses. Besides leading to a dramatic reduction in page load time for subsequent user visits, enabling caching can also significantly reduce the bandwidth and hosting costs for your site. Optimize caching in Make the Web Faster from Google’s Developers

Leverage browser caching

The point of using browser caching and expiry headers is to reduce the number of HTTP requests, which improves the performance for your returning visitors, instructing the browser to load previously downloaded resources from local disk rather than over the network, this means that the browser doesn’t have to re-fetch images, CSS and JavaScript every time our visitors comes back to our website.

If cached, the document may be fetched from the cache rather than from the source until this time has passed. After that, the cache copy is considered “expired” and invalid, and a new copy must be obtained from the source. Apache

It’s recommendable to configure the web server to explicitly set caching headers and apply them to all cacheable static resources (such as images, CSS, JavaScript, multimedia files, PDF, Flash objects, etc) and exclude dynamic resources like HTML. In newest browsers exist a feature which use the HTTP/S local caching support deciding how long cache resources that don’t have explicit caching headers; but it’s better set it manually to support older browsers and disable SSL resources caching.

Cache response headers

  • Expires or Cache-Control: max-age specify the time period during which the browser can use the cached resource without checking to see if a new version is available from the web server.
  • Last-Modified or ETag specify a characteristic about the resource that the browser checks to determine if the files are the same.
  • It’s important to specify one of Expires or Cache-Control: max-age, and one of Last-Modified or ETag; it’s redundant specify both Expires and Cache-Control: max-age or Last-Modified and ETag.

Recommendations

  • Use Expires over Cache-Control: max-age because it is more widely supported; set it to a minimum of one month, and take care with values up to one year because maybe you’re violating RFC guidelines,
  • Set the Last-Modified date to the last time the resource was changed to avoid the browser re-fetching,
  • Use fingerprinting to dynamically enable caching and tell the browser when a new version is available in the server,
  • Set the Vary header correctly for Internet Explorer (or remove it altogether if possible) because Internet Explorer doesn’t cache any resource that are served with this header,
  • Avoid URL hash collision in Mozilla Firefox ensuring that your application generates URLs that differ on more than 8-character boundaries,
  • Use the Cache-Control: public directive to enable HTTPS caching in Mozilla Firefox even if the other caching headers are explicitly set.

Leverage proxy caching

This technique let us use static resources cached on public web proxy servers, meaning that even first-time users visit our website can benefit from caching once a static resource has been requested by one user through the proxy (that resource is available for all other users whose requests go through that same proxy). We can indicate with Cache-Control: public header that a resource can be cached by public web proxies in addition to the browser that issued the request with these exceptions:

  • Most proxies don’t cache resources with an interrogation character (?) event if the Cache-Control: public header is present in the response,
  • Don’t enable proxy caching for resources that set cookies setting Cache-Control: private or serving those resources from a cookie-less domain,
  • Some public proxies have bugs that don’t detect the presence of the Content-Encoding response header resulting in compressed versions of CSS/JS files being delivered to client browsers that cannot properly decompress them; then use Cache-Control: private to disable proxy caching altogether for these resources, and set the Vary: Accept-Encoding response header to cache two versions of the resource (compressed and uncompressed) so the correct version of the resource is delivered based on the client request header.

Code

In Apache web servers we can use the module Mod_Expires.c to configure the expiration dates of the web resources taking the Mime-Type of the file and setting it the cache time (specified in years, months, weeks, days, hours, minutes and seconds); this is an example of how would look a real .htaccess file in a production environment, setting a default expiration time, long cache checking for generally unchangeable resources like a Favicon file, normal cache time for images and short times for CSS/JS files:

<ifModule mod_headers.c>
    Header set Connection keep-alive
</ifModule>

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 month"

    ExpiresByType image/x-icon "access plus 1 year"

    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/jpg "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"

    ExpiresByType text/css "access 1 weeks"
    ExpiresByType application/javascript "access plus 1 weeks"
</IfModule>

Credits

Explanation of HTTP caching in the HTTP/1.1 RFC, details on enabling caching in the Apache Caching Guide and the Google’s project Make the Web Faster. Tutorial made with the help of these resources.

Do you have a project idea? Let's make it together!