In the current state of the web, performance plays a quintessential role in a user’s experience. Having a fast and fluid web application has a direct effect on the success of a website’s conversions and traffic.
After all, good performance is all about maintaining users, so keeping them engaged will only lead to positive results in any business venture.
This is where the process of caching yields benefits if the user’s browser has access to an asset that was already retrieved, they are going to have a quicker experience as a result.
However, a more passive approach might be more effective here as even though changes can be made to improve caching, the logistics behind browsers caching process is subject to change in its version updates.
This can result in creating caching improvements that are no longer valid after a few months, essentially nullifying the work that went into it.
Let’s explore this further.
What is the function of the cache in HTTP?
The goal of caching in HTTP is to reduce the need to send requests and responses. Reducing both of these will result in fewer network round-trips as well as reduced network bandwidth requirements
This setting instructs the browser how long it should keep cached data after the initial retrieval.
Typically this is defined in seconds like so:
When specifying a custom amount of seconds in this header, we must be wary of potential updates to those files.
This can cause the user to be interacting with an earlier version of the website.
This is a frequently encountered scenario in tech companies, where the developers push a change to the product and the business side is unable to see the updates.
This results in some confusion between both areas of the company but is easily remedied by clearing the cache of the browser.
And while this situation might seem trivial, I have experienced it many times in different jobs especially during times of urgency and feature crunch. It can cause a small amount of temporary friction between business and development teams.
So these custom headers enable quite a lot of flexibility when it comes to configuring browser cache.
The no-cache directive indicates to the browser that cached versions of the requested resource can not be utilized without checking to see if there has been an updated version released since the initial caching occurred.
Typically, this check is done by using an additional header called an ETag. This is a unique token that helps to differentiate versions of the same resource.
The token will change on the server whenever the resource is updated. If the ETag in the browser is identical to the server then the cached version will be served to the user.
The header no-store acts in a more simplified manner when compared to no-cache. It essentially disallows browsers from storing any versions of a returned responses.
The process of downloading the assets every time is undoubtedly inefficient. However this is not without good reason, the use of no-store can help to disallow the storing of personal data/private information.
Some other request options include:
Cache-Control: max-age=<seconds> Cache-Control: max-stale[=<seconds>] Cache-Control: min-fresh=<seconds> Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: only-if-cached
Some other response options include:
Cache-Control: must-revalidate Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: public Cache-Control: private Cache-Control: proxy-revalidate Cache-Control: max-age=<seconds> Cache-Control: s-maxage=<seconds>
The full list of cache headers and their functionality can be found at the MDN docs.
However, this result can be stored in memory and the next time the same function is called, the already computed data is returned.
Essentially, it’s caching for functions.
This technique is only effective when the function is expected to return the same result. This is also called a pure function.
No other factors are taken into consideration including:
- Creates a references to a function as an input
- Create a cache to hold the result of previous function calls
- Future invocations of that function will return the cached results#
- If no cached value exists, will call the function and store the returned result in cache
If the function is relying on any of these factors, it should be noted that memoization can alter these results.
If there is memory available to be used for memoization, then it can be worth implementing in order to eliminate some code execution. It may not worth the extra effort is programs where memory is already sparse.
While it is unlikely that you will use memoization wherever possible in your codebase, there are plenty of 3rd party libraries that will do a much better job for us.
Take, for example, Reselect, which provides redux selector utilities that are not recomputed unless one of its arguments changes.
This is very handy in a Redux based application, as these selectors are constantly used to call upon subsections of data in the applications state.
Having these selectors of state already computed provides efficiency for more performant web applications.
So, if you don’t want to use 3rd party libaries and you are optimizing your functions just ensure that the functions to be memoized are pure functions.
How long does a website stay cached?
But, surely it can’t store endless amounts of cached data, right?
How long does a website stay cached?
Well, this very much depends on the browser, settings, and configuration of the HTTP requests and responses.
Typically, browsers reserve a finite amount of disk space to complete a task. If a user stops using the browser completely, the cache can persist indefinitely.
However, if the browser is used occasionally by the user, the stored data will last until the expiration date that was set either by the internal policy of the browser or the configuration of the HTTP headers.
If the user is very active using the browser, the length of time that the cache is stored can be extended to 10 minutes or less.
The process of caching such a small file is too heavy of an operation relative to the value it provides.
The majority of the logic for the user to interact is contained within these assets, so the ability to have them cached will allow the user to interact much faster on subsequent visits to the same page.