Decreasing response time

Fri, 09/11/2015 - 21:25

In case you haven't noticed my site has gotten faster.

I recently checked my page speed score using Web Page Test and Googles PageSpeed tool and found that my site was lacking a bit in terms of performance. Here's what I did about it.

Rendering

One of the recommendations was to move script and css tags to the bottom of the html file. This was fairly easy. Since I'm using Drupal, all I had to do was update the html.tpl.php file to the following.

<!DOCTYPE html>
<html lang="<?php print $language->language; ?>" dir="<?php print $language->dir; ?>">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <?php print $head; ?>
  <title><?php print $head_title; ?></title>
  <!-- HTML5 element support for IE6-8 -->
  <!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
</head>
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
  <div id="skip-link">
    <a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
  </div>
  <?php print $page_top; ?>
  <?php print $page; ?>
  <?php print $styles; ?>
  <?php print $scripts; ?>
  <?php print $page_bottom; ?>
</body>
</html>

Notice the 5th and 6th line from the bottom $styles and $scripts. They contain all the scripts that are added in processing hooks and are usually printed in the header. Moving them to the bottom allows the browser to receive and render the entire page content before loading scripts and styles. This might cause your users to experience a flash from for example a default font to a custom font since it won't be applied until the content has actually loaded, but it will allow the user to get a mental image of where the different elements are located on the page. You should consider whether the look and feel of you site is more important than perceived load time. Since I do not have anything special other than Twitter Bootstrap styling, I decided to improve the speed. I should mention that since I am including the bootstrap files from netdna.bootstrapcdn.com there is a chance that the user already has the file in cache from visiting other sites.

Expiration time

Another suggestion was to set an expiration time on static files. This would allow browsers to store static file for the amount of time I specified and save the browser from having to query my server to see if the files had changed.

To do this I added a .htaccess file in the site folder (where the settings.php file is). The file contains the following, which is proudly found on StackOverflow.

<IfModule mod_expires.c>
  ExpiresActive on

# Perhaps better to whitelist expires rules? Perhaps.
  ExpiresDefault                          "access plus 1 month"

# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)
  ExpiresByType text/cache-manifest       "access plus 0 seconds"

# your document html 
  ExpiresByType text/html                 "access plus 0 seconds"

# data
  ExpiresByType text/xml                  "access plus 0 seconds"
  ExpiresByType application/xml           "access plus 0 seconds"
  ExpiresByType application/json          "access plus 0 seconds"

# rss feed
  ExpiresByType application/rss+xml       "access plus 1 hour"

# favicon (cannot be renamed)
  ExpiresByType image/x-icon              "access plus 1 week" 

# media: images, video, audio
  ExpiresByType image/gif                 "access plus 1 month"
  ExpiresByType image/png                 "access plus 1 month"
  ExpiresByType image/jpg                 "access plus 1 month"
  ExpiresByType image/jpeg                "access plus 1 month"
  ExpiresByType video/ogg                 "access plus 1 month"
  ExpiresByType audio/ogg                 "access plus 1 month"
  ExpiresByType video/mp4                 "access plus 1 month"
  ExpiresByType video/webm                "access plus 1 month"

# htc files  (css3pie)
  ExpiresByType text/x-component          "access plus 1 month"

# webfonts
  ExpiresByType font/truetype             "access plus 1 month"
  ExpiresByType font/opentype             "access plus 1 month"
  ExpiresByType application/x-font-woff   "access plus 1 month"
  ExpiresByType image/svg+xml             "access plus 1 month"
  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# css and javascript
  ExpiresByType text/css                  "access plus 2 months"
  ExpiresByType application/javascript    "access plus 2 months"
  ExpiresByType text/javascript           "access plus 2 months"

  <IfModule mod_headers.c>
    Header append Cache-Control "public"
  </IfModule>

</IfModule>

Result

As a result of the above two changes I have gone from a 82/100 score to 91/100 on Google and from an F to an A on WebPageTest in regards to caching, which is pretty cool.

I also did a simple performance test using Apache jMeter and Jenkins CI where I can see that the average response time went from 150ms to 90ms. This is shown in the graph in the image. (Note: The first build marked with #1 on the graph is lower, but this was a test run without actual parameters, so it is not included.)