When developing web applications, you can do some mistakes related to basic peculiarities of TCP and HTTP. The post explains some of the pain points and shows approaches to avoid such problems.
TCP connection establishment
The TCP connection establishment takes some time, because TCP uses a three-way handshake. So 3 packages are necessary before the TCP connection is established and can be used for HTTP requests. This behavior leads to an increased latency until the page content reaches the user’s browser.
The solution for this is simple: Use HTTP 1.1 (instead of HTTP 1.0) as it supports the reuse of TCP connections. To be honest, this is something most applications don’t do wrong as modern browsers and web servers simply do it the right way nowadays. Nevertheless, I think this is useful information for web developers as you should know that something is potentially wrong if you read HTTP 1.0 (e.g. in some log file).
Effects of latency and bandwidth
Latency and available bandwidth of the user’s internet connection is something that massively influences the usability of your web application. Regarding this topic, you can do some mistakes. This is because HTTP doesn’t use the duplex capability of TCP connections. Even with HTTP 1.1, requests are executed in a serial order. A new request can only be sent using the existing TCP connection if the response of an earlier request is completely transferred.
If your application consists of many small resources and the user’s internet connection is affected by a high latency, your TCP connection is waiting most of the time with only short times of data transfers. So this causes a waste of time and bandwidth.
In summary, you should prefer few bigger resources over many small ones in your web application. But how can you achieve this?
- Use CSS sprites or an icon font (like Font Awesome) to avoid lots of small icon files
TCP slow start
On Wikipedia, TCP slow start is explained as follows:
Slow-start is part of the congestion control strategy used by TCP, the data transmission protocol used by many Internet applications. Slow-start is used in conjunction with other algorithms to avoid sending more data than the network is capable of transmitting, that is, to avoid causing network congestion. The algorithm is specified by RFC 5681.
The slow start algorithm is explained this way:
Slow-start is one of the algorithms that TCP uses to control congestion inside the network. It is also known as the exponential growth phase.
During the exponential growth phase, slow-start works by increasing the TCP congestion window each time the acknowledgment is received. It increases the window size by the number of segments acknowledged. This happens until either an acknowledgment is not received for some segment or a predetermined threshold value is reached. […]
So in summary, this behavior causes the TCP connection to not use all of the available bandwidth. This means the TCP connection needs some time to warm up.
You should do two things to reduce negative effects due to TCP slow start:
- Reduce the overall size of the resources to be loaded
- Use HTTP compression
- Use pure CSS to achieve some styling instead of using images
- Prioritize the important stuff
- Load optional functionality on demand
[…] A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. […]
In reality, most current browsers open up to 6 or even 8 connections per server. Regardless of the concrete number, this causes that only a limited number of resources can be transferred in parallel. You can see this by using the network analysis of the developer tools in your browser. It will look like this:
With this in mind and the fact that HTTP potentially wastes available bandwidth (due to the facts above), you should again try to reduce the number of requests necessary to load your application. Ideally, the requests needed in parallel should be <=6 to not cause resource loading to be deferred on any current browser.
Caching is one of the most powerful tools to optimize your application. Every resource not transferred can’t be affected by the effects explained above.
To make it really work reliably you should have a look at perfect caching.
Some thoughts on optimization
One note for Java developers: When using GWT, most of the aforementioned best practices are automatically done for you.
The future of HTTP
HTTP/2 will solve many of the problems that exist in HTTP 1.1, but HTTP/2 isn’t final yet (late 2014)… However when HTTP/2 is final it will take some years for the adoption of the new protocol and for client and server software to be really available in companies. So we will have to deal with these problems many years.