Vanand Mkrtchyan
Tech Lead
For a while, the digital environment has been focused mostly on customer experience. We may not be mistaken in saying that customer experience is at the center of everything. Regardless of how beautiful and functionally flawless your product is, it will cause enormous damage to your business if it is lagging in speed.
As experts in software engineering and website performance, we want to address what website performance is, how it is measured, and which factors are critical for tracking performance. Let’s refer to the topic in more detail, which is, on one hand, underestimated by many specialists and, on the other hand, shrouded in mystery. What is caching and “what is it eaten with?”
The concept of web performance is all about making websites fast. There are two core aspects of website performance:
We will not dive deeper into performance issues and how to fix them from a usability perspective because they are mostly individual. But instead, we will explore page load performance.
Page load performance is about how fast your website appears to visitors and how quickly it becomes interactive.
Let’s start with some statistics to show how important the page load is and how negatively it may affect your business in the case of disregarding it.
Google page load time (the primary search ranking factor for SEO) reveals how this criterion may affect your performance. This data will help you understand the importance of page load time and why you need to care about its speed.
What does this mean? There is one simple truth. The faster your page loads, the higher its user engagement, which affects search engine rankings. The page speed should be as fast as possible so as not to compromise the customer experience.
The major steps in page load and responsible for speed are the following;
Long story short, based on our knowledge of how the web works, we know that whenever a user is visiting our website, the browser is:
This means that we have to split website performance into several parts, which are considered main metrics (KPIs) to measure the overall performance.
Since the hardware costs have decreased after the mobile/tablet "revolution", high-performance devices have become more accessible to users. The overall page rendering stuff is not a big deal when we are talking about websites (for complex applications it may be an issue even now), and since we cannot cover EVERYTHING in a single article, let’s focus on the most painful issue: the Time to First Byte metric.
Time to First Byte is the time between the browser requesting a page and the time it receives the first byte of information from the server. This time includes a DNS lookup and establishing the connection using a TCP handshake and an SSL handshake if the request is made over HTTPS.
TTFB is the time it takes between the start of the request and the start of the response, in milliseconds:
TTFB = responseStart - navigationStart
So what is caching? Caching is the process of remembering the result of an expensive operation to efficiently reuse previously retrieved or computed data and speed up reads.
Let's imagine that we have a function that is doing some heavy calculations, and let’s call it calculateHeavyStuff()
. Let's wrap that function in another function and call it cache()
.
// cache.js
export function cache(func){
let value;
return () => {
if( typeof value === "undefined" ) {
value = func()
}
return value
}
}
// calculateHeavyStuff.js
import {cache} from './cache'
export function calculateHeavyStuff(){
// do some heavy calculations here
}
export const cachedCalculateHeavyStuff = cache(calculateHeavyStuff)
As you can see, the whole thing the cache function is doing is wrapping the argument function and remembering its value. On the first call of cachedCalculateHeavyStuff
, the value will be undefined, so the cache function will call the calculateHeavyStuff
function, assign the return value to the variable, and return it. The magic starts on the second and next calls. If you call cachedCalculateHeavyStuff
once again, the if
statement will not be undefined, so the if
condition will be false
, which means that the calculateHeavyStuff function will not be called but the previous value will be returned.
The same kind of thing is happening when we cache HTTP responses: the cache service calculates the response and stores it somewhere, and for the next calls it’s returning the stored response instead of calculating the response once again.
The same is for DB data aggregations, etc.
Now let’s talk about the levels of caching in the HTTP request-response workflow. By saying levels, we mean where the cached data is stored in that flow:
In this caching method, the cached resource is stored on the user's browser. If the visitor is accessing the site based on cache headers, the browser decides to keep cached resources in browser cache storage, and on the next attempt, cached resources are brought from that storage instead of the server. The downside of this method is that caches are stored per user and per browser.
In this caching method, the cached resource is stored on the server. There are different approaches to using server-side caching. We can either limit only calls to the DB or even heavy functions/calculations as well, and that’s why in the image below we have just a partially gray server.
In this caching method, the cached resource is stored on special cloud servers called data centers that are spread around the world. Here we are putting an external service that is providing edge caching functionality between our client and servers, so connections to servers are very few since the caching provider is getting the cache resources and spreading them across all necessary data centers. Typically, since these kinds of services lie between the client and server, they also provide DNS services and SSL certificates. By using this kind of service, you will notice a decrease in time for all the factors affecting TTFB metrics:
Since these services have data centers all around the world, the browser will get the response from the nearest one, meaning not only is the data cached, but the time to connect to the server and get the response back is also minimal.
Everything is perfect, right?
Not always! Let’s talk about the downsides and solutions to this method.
Winter is coming...
What we have discussed may perfectly apply to static or old-school websites.
We've faced several revolutions on the web: from dial-up to wireless connectivity, and from slow devices to multiple types of powerful gadgets that bring new challenges. And now again, we have new challenges along with those new opportunities.
We may think that having faster connections and more powerful devices may solve our problems, but the fact is that it’s just bringing new features and challenges to consider, and as always, performance is staying a top priority for every product.
How are dynamic sites and pages different from static ones? We know that pages have different and unique paths, and caches are stored by path, so having a dynamically increasing number of pages but also having updates on those pages, dom manipulations, etc.
In previous decades, we had a simple structure for websites.
Now we have the following picture:
Need to check your website performance?
The concept of web performance is all about making websites fast, including making slow processes appear faster. There are two core aspects of website performance:
Caching is remembering the result of an expensive operation to speed up reads.
Page load performance is about how fast your website appears to visitors and how quickly it becomes interactive.