BLOG STACK

Web performance. Part two of two: Optimization

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.

The request

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.

Waiting time

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.

DNS lookup

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.

TCP

This is the time it takes to establish a TCP connection with the server which includes the TCP handshake and potentially subsequent retries.

SSL

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.

Content download

This is the times it takes for the whole response of the server to download on the client’s end.

The HTML

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 rest

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

Optimized

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.

Page caching

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.

HTTP caching

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.

Query 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.

Be concise

Optimized

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.

Image formats

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.

Sprites

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.

CSS

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).

Above-the-fold delivery

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.

Minification

The CSS and JavaScript files your server delivers are usually very long and verbose. They contain long names, a lot of spacing, long comments, and optimized sections of code. To make them as small as possible, use minification, a process that makes your scripts as small as possible without changing behavior at all.

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.

Large libraries

Each JavaScript library that you try to load on your website will inevitably slow it down. The problem gets even worse when you’re trying to use large libraries like jQuery that take a significant time to download.

This wouldn’t be such a big issue if the libraries were used to a somewhat decent capacity but, in most cases, only 5% or less is being used from their full potential. If this is your case as well, try to avoid using libraries and write that missing functionality in pure JavaScript. The work may be a bit involved but the performance you get out of it should be significant.

If you’re not fully invested in the JavaScript ecosystem, you might want to consider Dart. Dart is very well supported and it compiles back to JavaScript if you’re worried about backwards compatibility. The reason I’m mentioning Dart here is because of one of its features called Tree shaking only loads the parts of the libraries that you are actually using and packs them into a single minified Dart or JavaScript file.

Inefficient JavaScript

Apart from the issue of slow loading times there’s still the issue of responsiveness. Make use of hefty, inefficient JavaScript, and you’ll be left with a website that requires seconds to respond to your input. Ten years ago, sites used to have simple and fast client-side scripting and the connection was the bottleneck. Nowadays, it’s quite the opposite.

Covering how to and how not to write JavaScript would be the topic of a separate article, but I will leave here some terrific articles to help improve your scripting. Google has a simple and straightforward guide, but they can also make mistakes. For a more complete guide see Smashing Magazine’s article on the topic that goes in great depth to teach you how to leverage all the V8 speed.

Let everything breathe

Optimized

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.

Load distribution

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.

Server bottlenecks

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.

Ads

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.

Smart Managed WordPress Hosting

Presslabs provides high-performance hosting and business intelligence for the WordPress sites you care about.

Get Started