A tangled mess of web requests

Website Performance - Removing Unneeded Requests

Continuing my speed challenge series against Dri.es, in this post I'm going to focus on removing unneeded browser requests.

When rebuilding this site, shipping it quickly was the focus. With this in mind, I used the Bootstrap theme to put together a quick sub-theme with most of its default settings. This produces a decent looking site rather quickly, but it also comes at a frontend performance cost.

Waterfall view of page load
Waterfall view of cashwilliams.com (actually the staging version of this site).

I used WebPageTest.org to generate a waterfall view of a page load. If you aren't familiar with waterfall views, Nooshu.com has a very in depth article explaining how to read them.

The waterfall view shows there are 10 total requests during the page load. The first step was to identify each of these requests and determine a way to remove them.

Request #6, #7, and #8 are all coming from jsdelivr.net, which is the default behavior of the Bootstrap theme.

Request #9 is coming from fonts.googleapis.com, and I chose not to use this font at all by overriding it in my sub-theme's CSS. Since the CSS file requesting the font is coming from the jsdelivr.net CDN, I couldn't remove the reference to it.

The Cost of the Connection

It is interesting to take a look at the specific timing around each connection. WebPageTest.org also renders a table breaking down the different connection stages.

Request Timing Details
The request details view of homepage load for cashwilliams.com.

The chart provides some interesting details into the cost of each new request. Request #1 has a DNS lookup time of 27 ms, then a connection handshake of 32 ms, and a SSL negotiation of 74 ms. This means the connection cost of requesting a file from the domain cashwilliams.com for the first time is 133ms. Once the initial request is downloaded and parsed, the browser requests the next four files from the same domain in parallel (this is reflected in the waterfall view above as well). The key point here is the connection cost for requests #2 through #5 is zero.

The connection cost comes back again at request #6 as this is from a new domain. The DNS lookup time in this case is a full 132 ms. Following that the connection handshake of 30 ms and the new SSL negotiation of 68 ms brings the total connection cost for request #6 to 230 ms. Almost a forth of the total page load time is the browser attempting to make this new initial connection to the jsdelivr.net server.

The important takeaway here is, with these standard file sizes, the time to download the file itself is negligible compared to the time it takes to initiate the connection to request it.

Addressing the Issues

Resolving these issues was a straight forward, but lengthy process. I installed a SASS compiler and added both Bootstrap and the Yeti Bootswatch files into the main SASS include file. Then it was possible to remove request #9 for the default font included in the Yeti theme (rather than just overriding it with additional CSS in a later file), and adjust a few other default variables to maintain the look of the existing site. 

Editing a SASS file in Acquia RemoteIDE.
Editing the default variables in Acquia's web based RemoteIDE tool.

Now that a single custom CSS file is generated for the sub-theme, Drupal's aggregation can compile it in with the existing CSS files. This effectively folds requests #6 and #7 into the requests #2 and #3.

I also adjusted the sub-theme's library config to point to the local copy of the Bootstrap javascript files. This places the contents of request #8 within the existing files served from requests #4 or #5.

The Results

Running the WebPageTest.org test again with these deployed changes returns a much cleaner version of the connection details table.

Connection Request Details
Request Details for cashwilliams.com after initial optimization.

The screenshot shows only one connection is made for the entire page load, which has a 130 ms connection cost.

The final evaluation of this change is to check in with the official metric as measured by SpeedCurve.

Speedcurve Removing Requests

A signification dip in SpeedIndex is shown at the time this change was deployed. The gap between Dri.es and CashWilliams.com is now much closer, with Dries 20% faster.