Welcome to our second part of the article concerning web performance. In case you missed the first part which deals with assessing the performance of your website, you can take a look over it here.
This second part will explore three concepts that, once taken into consideration, will lead to a much better performing website.
#From first request to a fully rendered web page
Before starting with the first concept, let’s first do a brief examination of how a web page is rendered.
Whenever you type a URL into a browser and hit return, the browser will make a GET request to the URL you specified. This is how a request is split:
Use the above buttons or the arrow keys to navigate.
Sometimes the web browser has a lot of things to do and maybe even other requests to handle. When its hands are tied like this, it has to put any subsequent request on pause until its current task queue is empty enough to start working on it.
This is the time the browsers spends asking the DNS server for the IP behind the request’s domain. Modern browsers actually cache this info so only the first lookup on a domain will be noticeable.
This is the time it takes to establish a TCP connection with the server which includes the TCP handshake and potentially subsequent retries.
This is the time it takes for the SSL handshake to be performed. Of course, this only takes place when the connection is using HTTPS.
Time to first byte
This is the time it takes for the server to get the client’s message, to compute a reply, and to start sending the first byte. It’s usually the longest part of the request, if on a good connection, due to the server’s usually lengthy processing time.
This is the times it takes for the whole response of the server to download on the client’s end.
That first request that you make will only fetch the HTML of the web page. Your browser then parses it and constructs the DOM tree. Before showing you anything on the screen, the browser will do a request like the one above for every picture, style sheet, and script that is mentioned in the HTML. Some of these files may already be found in the browser’s cache which will stop it from actually making the request.
The browser continues with the style sheets and scripts that are mentioned in the head of the HTML. It creates what is called a CSSOM from the sheets and runs all of these scripts. After that, it goes on to create the final rendering tree that it will use to draw the web page.
#Web performance optimization concepts
#Don’t repeat yourself
If there’s something that can be done only once, try not to do it multiple times. This may seem like a pretty obvious and straight-forward thing, but computers tend to repeat a lot of tasks just because it’s easier for a programmer to repeat a task rather than memorize it. Imagine a website that tries to load the jQuery library for every single web page that you visit. Quite a waste, isn’t it?
The idea here is to try and find things that repeat themselves and only run them once by saving the result and using that. This concept is called caching and we’re going to explore in multiple occasions.
To solve the problem of a single page being generated by the backend countless times, caching only allows it to generate once and then saves the resulting HTML. As long as the webpage doesn’t change, the server will respond with the already generated HTML which is considerably faster. When it does change, the cache will generate a newer version of the HTML file and serve that one instead.
In the case of WordPress, you can use a plugin like W3 Total Cache to enable caching. Some hosting companies–us included–offer integrated caching which is faster and more reliable.
In the end, caching will undoubtedly help a lot as long as your website doesn’t have extremely volatile content, because it will lower your response time considerably.
A lot of the images, style sheets, and scripts that your website is using don’t change very often, maybe not at all, so it would be nice if you could cache this content on the client’s computer. Luckily, most modern web browsers offer this possibility. By using a couple of specific HTTP headers you can easily control the browser’s cache.
You can find here a detailed guide to HTTP caching.
Some queries may become extremely frequent. If your website does a lot of reads and doesn’t alter the database too much, using query caching can be extremely helpful. The database reads data from the hard disk to answer your queries, so usually these queries take quite a bit of time. Caching keeps some of these most used results in memory for fast access.
Here is a guide telling you how to implement query caching in MySQL. It’s very important to consider the parameters you’re going to use: a huge cache coupled with constantly different queries will result in caching useless queries. There’s a nice writeup on the matter here with a few useful tips.
Concise as opposed to wasteful. Whenever you’re doing something make sure it’s useful, optimized, and as short as possible. You need to know that you’re not wasting the time of the person in front of the browser.
Each image needs to be saved in a specific and well defined format in order to be displayed on other devices. Some of the most popular image formats are JPG, PNG, and GIF. GIFs are mostly used for animation and not much else, but the other two have very specific purposes.
PNGs are used for simple, geometric shapes and usually look far better than JPGs of similar sizes in this particular use case. JPGs work better with photography, although PNGs can handle the job pretty well too.
If your website uses a lot of elements in the form of images, it needs to make a separate request for each one. This is not acceptable since each requests adds milliseconds to your loading time.
A really simple way to solve this is to create a single image that contains all the other images inside of it with no overlaps which is called a sprite. This has not one, but two advantages. The first is that it requires only one single request instead of tens or more. The second is that it lets the image format better optimize all these images together–sprites will almost always be smaller than all the pictures together.
After you have the sprite, you can use CSS to embed it into your website. Here’s a simple tool to get you started with sprites.
Where possible, try to use CSS instead of image-based elements. Apart from having a much better quality, they’re also smaller and don’t require any request; they come with the CSS files.
Of course, you won’t be able to draw everything from CSS, and some things will simply take too much time to do in CSS. In these cases, feel free to use sprites (preferably a single one).
Although not a very popular concept, above-the-fold delivery may prove to be a good solution if your pages are extremely long and heavy, and you can’t seem to optimize the speed anymore.
The idea behind it is very simple. You divide everything in multiple CSS, JS files, and sprites and you tell the browser to first fetch only the ones that deal with what the user sees right now, and only later fetch the rest. Thus, the user will notice how fast the first part of the page is loading, and he will be able to start viewing the content long before the page finished loading.
You can use a tool like minify for this task. On WordPress, W3 Total Cache also offers minification, or you can try Better WordPress Minify if you don’t require caching.
Too many files
Another problem is when your scripts are split into many files. This, obviously, results in a lot of requests. Luckily, minification tools and plugins also offer the possibility of combining your scripts together.
#Let everything breathe
Sometimes one of your components may be doing too much work, thus slowing up the whole website. Try to make sure that each component of your website has enough room to breathe.
If your website is constantly under heavy load, and you’re the one managing the servers behind, you might want to consider splitting the load. Distribute it on multiple servers when possible.
A good start for this may be Wikipedia or, if you’re already accustomed to the practice, you can take a look over a simple implementation in Nginx.
Again, if you’re the one managing your backend, make sure there are no bottlenecks. Check your CPU, RAM, and I/O speeds to see if they’re working at optimum capacity.
In case something is wrong, you may want to do some profiling on your app and see which part of your logic is causing the slowdowns.
Also remember to take a look at all the running processes and make sure there’s nothing there you might want to kill.
A really easy way to do profiling on almost any kind of web application is to use a service like New Relic’s APM. This provides in-depth analysis of your code and tells you where it is the slowest, it finds out which queries are the most frequent, it tracks your errors etc. What is more, they have a free plan that’s great to use for web performance tuning.
Content Delivery Network
As was previously mentioned, your backend shouldn’t be bothered with anything else apart from its main job, generating and serving HTML. Serving assets like scripts and images should be handled by a totally different machine. And since these are usually the larger parts of websites, the best solution for this is to use a Content Delivery Network.
The CDN is usually optimized to deliver big content fast, irrespective of your location, and is especially great for a worldwide audience.
It can either be included in your hosting offer, or you can sign up to a CDN provider like CloudFlare.
Unfortunately, because of the way targeted ads are being created and distributed, there is no speedy way of delivering them to your users. If you’re implementing them in a not too exotic manner, there will be very little room for improvement. What you can do, instead, is to consider and reconsider the number of ads your are displaying. Try multiple layouts with different number of ads and see how it influences your response times and earnings.
What you can try to do is strike a deal with a possible partner who may be interested to advertise on your website. This way you can design and optimize the ad yourself with almost no impact on web performance.
And before I close this chapter, I want to first speak about Quora. The company raised a lot of money and has a giant valuation, but it doesn’t use advertising or any kind of monetization. A possible answer to why they’re not using ads can be found here. In fewer words, people find Quora, its idea, its content, its audience, and its team much more valuable than what ads could bring back. I’m not saying giving up on ads is optimum; Quora suffers from a quite bit of pressure because it doesn’t yet have a clear monetization plan. What I’m trying to say is that you should concentrate on delivering good content and services to your faithful audience, and that ads shouldn’t interfere or lower the quality of your website.
#Where to go from here
A great place to continue with the optimization would be on Google’s Web Fundamentals Optimizing Performance guide. If you manage to implement everything that was discussed and even go through part of the articles in this guide, your website should be in the fastest 1% in its niche.