Introduction

When recently looking for information about how Google does its SEO (Search Engine Optimization) picks for various sites, I stumbled upon the PageSpeed Tools. This is a site where you can analyze your website to see its performance and it also makes suggestions. This is a good idea, since if you want to improve your SEO, you’ll definitely want to use this tool to get your site a better ranking on Google.

To use the tools simply go to: https://developers.google.com/speed/pagespeed/insights/ and then enter the URL that you want to analyze, and then click the Analyze button, and it will give you the results for mobile and desktop devices.

I ran this on a web app site that I created using Symfony, and then I realized I needed to optimize my Apache HTTP Server. This is what this article is about.

Before gzip Compression

We need to verify first that gzip compression is not running, and the best way to do this is using a FireFox browser. We need to open the FireFox developer tools and in particular the Network tab. A quick way to do this is use the key sequence CTRL+SHIFT+Q, and then press SHIFT+F5 on your keyboard to do a hard refresh (CTRL+F5 forces a full refresh and disables caching) of the web page you are checking.

In my case the below screenshot is what my web page looked like before gzip compression was enabled:

Before gzip compression

In particular you should look at both the “Transferred” and “Size” columns. The “Transferred” column shows what was actually sent, and “Size” shows the original size of the file. In this case both the “Transferred” and “Size” columns exactly match; so there is no compression whatsoever.

Enabling gzip Compression

Most modern browsers can handle gzip compression. That means the HTTP server sends a gzip file and the browser automatically decompresses the file, which reduces the amount of data that needs to be sent from server to client.

Apache uses the mod_deflate module for compression, and to use that the mod_filter module is required. You need to make sure they are enabled on your Apache HTTP Server by editing “/etc/httpd/conf/httpd.conf” – the configuration file. In my case I’m using CentOS (similar to RHEL) which has httpd version 2.2, and the location of your httpd.conf might be different. Regardless open the httpd.conf file and search for the following lines and uncomment them to enable them:

LoadModule deflate_module modules/mod_deflate.so
LoadModule filter_module modules/mod_filter.so

Then to enable gzip compression you need to add a deflate filter to you httpd.conf file; so go to the very bottom of the httpd.conf file and add the following line:

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript

The above line enables compression for the most common text files; you can add additional mime types as needed. Then after making the above changes, you’ll need to restart your Apache httpd server. Use the following command to do that:

service httpd restart

After restarting the Apache HTTP server, then in FireFox, use CTRL+F5 to fully refresh your browser. The below screenshot is what I got when I made the changes:

After gzip compression
After gzip compression

Now you’ll notice the “Transferred” and “Size” columns are different. The “Transferred” column is smaller. Also, if you click on any of the items in the list, for example I clicked on “jquery-3.1.1.min.js”, then you’ll see the “Headers” tab. Then click the “Raw headers” button. You’ll see something like the below screenshot:

gzip headers

So what the Request headers show is that the client is requesting gzip compression (it supports gzip), and the Response headers is showing that it accepts the encoding (response is using gzip). This confirms that the gzip compression is working.

Before Browser Caching

Another way to optimize your Apache HTTP server’s performance is to enable browser caching. This is done using the mod_expires Apache module. What this change does is sets the “Expires” Response headers. If the Expires Response header date stamp is after the current time, then the browser will not request the file and uses the file that is stored in its cache.

To enable mod_expires, we open the httpd.conf file and search for the following lines:

LoadModule expires_module modules/mod_expires.so

If the above line is commented, then we need to uncomment it. We also need to add the following expires for the various mime types. Just add these to the bottom of the httpd.conf file:

<IfModule mod_expires.c>
   # Turn on the module.
   ExpiresActive on

   # Set the default expiry times.
   ExpiresDefault "access plus 2 days"
   ExpiresByType image/jpg "access plus 1 month"
   ExpiresByType image/gif "access plus 1 month"
   ExpiresByType image/jpeg "access plus 1 month"
   ExpiresByType image/png "access plus 1 month"
   ExpiresByType text/css "access plus 1 month"
   ExpiresByType text/javascript "access plus 1 month"
   ExpiresByType application/javascript "access plus 1 month"
   ExpiresByType text/css "now plus 1 month"
   ExpiresByType image/ico "access plus 1 month"
   ExpiresByType image/x-icon "access plus 1 month"
   ExpiresByType text/html "access plus 900 seconds"
</IfModule>

The above sets the Expires header for most mime types to 1 month (which is reasonable) and html to 900 seconds (15 minutes). And then when you’ve made the above changes restart the Apache HTTP server using the following command:

service httpd restart

Now you can request the web page again. This time don’t press CTRL+F5, instead just re-enter the web page URL in the browser URL field. In the FireFox network tab it looked like the following screenshot showing browser caching is working:

browser caching enabled

Notice in the “Transferred” column that it shows “cached” indicating browser caching is working. If you click on one of the cached requests, and then click on the Raw headers button, I saw the following example for my main.css file:

expires headers enabled

The fact an “Etag” appears and the both a “Cache-Control” and “Expires” header appears, this shows browser caching is working. The value of “2,592,000” for the max-age, works out to 1 month in seconds; which matches our httpd.conf changes that we made above.

You may not have noticed, but in the screenshots, the “GET” for the file “/app_dev.php/” it returns a “html” type, and also if you look at the Raw headers, the “Cache-control” shows “no-cache” for the html file. This is because my web application uses the Symfony framework, and I need to use Expiration caching in Symfony itself – which I will cover in a different article.

Advertisements