Optimizing WordPress Loading Speed With header.php & .htaccess

Optimizing WordPress Loading Speed With header.php & .htaccess

Tutorial Details
  • Program: WordPress & .htaccess
  • Difficulty: Easy
  • Estimated Completion Time: 5-10 Minutes

Website loading speed matters a lot for every blog/website, especially for people with shared hosting – which is the cheapest available hosting service. Here are a few .htaccess and header.php tricks to increase your website loading speed by 50-70%


Web performance is getting more and more attention from web developers and is one of the hottest topics in web development. First and foremost, loading speed is more than a feature. Speed is the most important feature. If your website or blog is slow, people won’t use it.

What speed means to internet giants:

  • For Google – 500 milliseconds of extra load time caused 20% fewer searches
  • For Yahoo – 400 milliseconds of extra load time caused a 5-9% increase in the number of people who clicked “back” before the page even loaded
  • For Amazon – 100 milliseconds of extra load time resulted in a 1% drop in sales

Google, in their ongoing effort to make the web faster, blogged that “we’ve decided to take site speed into account in our search rankings.”

So a slower website will even decrease your search engine ranking too.

Thus loading speed matters a lot. CDN (Content Delivery System) are pretty good for this purpose, but up to a limited extent, and good CDN providers are a little costly.

The good news is that some of the most important speed optimizations can be easily done with simple .htaccess tricks. These can make any website load faster by compressing content and enabling browser caching, and follow the Best Practices for Speeding Up Your Web Site from Yahoo!’s Exceptional Performance team and doesn’t cost a cent.


Step 1 Gzip File Compression

Compression reduces response times by reducing the size of the HTTP response.

It’s worthwhile to gzip your HTML documents, scripts and stylesheets. In fact, it’s worthwhile to compress any text response including XML and JSON.

Image and PDF files should not be gzipped because they are already compressed. Trying to gzip them not only wastes CPU but can potentially increase file sizes.

File compression also saves some amount of your bandwidth.

With .htaccess

  • For Apache Servers

    mod_pagespeed is an Apache module developed by Google and its command directive can be used just like other modules.

    Currently only GoDaddy and DreamHost support the mod_pagespeed module, so if you host with them just copy and paste the following code to your .htaccess file:

    			<IfModule pagespeed_module>
    				ModPagespeed on
    				# using commands,filters etc
    			</IfModule>
    		

    Many of you may be hosting with other hosting providers which do not support the mod_pagespeed module.

    You can use the mod_deflate module (Apache 1.3x used mod_gzip but since Apache 2x mod_deflate is used)

    			<ifModule mod_deflate.c>
    				AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
    			</ifModule>
    		
  • For Nginx Servers

    If you host on a Nginx webserver copy the following to your .htaccess to enable gzip compression.

    			server {
    				gzip on;
    				gzip_types text/html text/css application/x-javascript text/plain text/xml image/x-icon;
    			}
    		

With header.php

If your server doesn’t support mod_deflate or mod_gzip you can use this PHP script for gzip compression which works on both Apache and Nginx

Just copy this into your theme’s header.php

<?php
if ( substr_count( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) ) {
	ob_start( "ob_gzhandler" );
}
else {
	ob_start();
}
?>

Below is the bar graph depicting my website’s loading speed without and with gzip compression.


Step 2 Disable ETags

ETags (Entity Tags) are a mechanism that web servers and browsers use to determine if the component in the browser’s cache matches the original server. Etags are added to provide a mechanism for validating entities that is more flexible than the date of last modification. An ETag is a string that uniquely identifies a specific version of a component. The limitations of this format is that the string is quoted. The origin server specifies the component’s ETag using the ETag response header.

To disable ETags, paste this into your .htaccess file

Header unset ETag
FileETag None

Step 3 Use Browser Caching

With browser caching, we’re explicitly instructing browsers to hang onto particular files for a specified period of time. When the file is needed again, the browser is to pull from its local cache instead of requesting it from the server again.

Running a website without caching in place makes as much sense as driving to the store for a glass of water every time you’re thirsty. Not only is it impractical and short-sighted, it takes more work!

Browser caching is really useful to get returning users; i.e. it may build loyal permanent visitors to you and also saves a lot of your bandwidth.

A first-time visitor to your page will make several HTTP requests to download all your site’s files, but by using the Expires and Cache-Control headers you make those files cacheable. This avoids unnecessary HTTP requests on subsequent page views.

  • For Apache Servers

    Apache enables through the mod_expires and mod_headers modules.

    The mod_expires module controls the setting of the Expires HTTP header and the max-age directive of the Cache-Control HTTP header in server responses. To modify Cache-Control directives other than max-age, you can use the mod_headers module.

    The mod_headers module provides directives to control and modify HTTP request and response headers. Headers can be merged, replaced or removed.

    Add these rules to .htaccess for setting Expires headers:

    			# BEGIN Expire headers
    			<ifModule mod_expires.c>
    				ExpiresActive On
    				ExpiresDefault "access plus 5 seconds"
    				ExpiresByType image/x-icon "access plus 2592000 seconds"
    				ExpiresByType image/jpeg "access plus 2592000 seconds"
    				ExpiresByType image/png "access plus 2592000 seconds"
    				ExpiresByType image/gif "access plus 2592000 seconds"
    				ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
    				ExpiresByType text/css "access plus 604800 seconds"
    				ExpiresByType text/javascript "access plus 216000 seconds"
    				ExpiresByType application/javascript "access plus 216000 seconds"
    				ExpiresByType application/x-javascript "access plus 216000 seconds"
    				ExpiresByType text/html "access plus 600 seconds"
    				ExpiresByType application/xhtml+xml "access plus 600 seconds"
    			</ifModule>
    			# END Expire headers
    		

    .htaccess rules for setting up Cache-control header:

    	
    			# BEGIN Cache-Control Headers
    			<ifModule mod_headers.c>
    				<filesMatch "\.(ico|jpe?g|png|gif|swf)$">
    					Header set Cache-Control "public"
    				</filesMatch>
    				<filesMatch "\.(css)$">
    					Header set Cache-Control "public"
    				</filesMatch>
    				<filesMatch "\.(js)$">
    					Header set Cache-Control "private"
    				</filesMatch>
    				<filesMatch "\.(x?html?|php)$">
    					Header set Cache-Control "private, must-revalidate"
    				</filesMatch>
    			</ifModule>
    			# END Cache-Control Headers
    		

    Note:

    1. There is no need to set the max-age directive with the Cache-Control header since it is already set by the mod_expires module.
    2. must-revalidate means that once a response becomes stale it has to be revalidated; it doesn’t mean that it has to be checked every time.
  • For NGINX Servers

    The corresponding .htaccess settings in Nginx would look something like this:

    (The example below would tell your visitor’s browsers to hang onto HTML, CSS, Javascript, images and favicon for an hour)

    			location ~* \.(jpg|png|gif|jpeg|css|js)$ {
    				expires 1h;
    			}
    		

Step 4 Reduce MySQL Database Size

Since WordPress 2.6, WordPress autosave posts while writing which remain even after the post is saved as revision in the MySQL Database. Bigger database also sends the site load time higher. I suggest removing revision feature.

Paste the following to wp-config.php to disable revisions:

define('WP_POST_REVISIONS', false );

If you decide to keep the revision feature on you may also choose to keep the revisions on the database for a fixed number of days, e.g. 10 days.


More…

  1. Adding the expires header does not affect the loading time of the website for a first visit, but you’d be surprised how much the page load is reduced for the next page view / visit from a returning visitor.
  2. Track how your site is doing on: display loading number of queries and time.

    Just paste the following code after the copyright text in your theme’s footer.php:

    			<?php echo get_num_queries(); ?> queries in <?php timer_stop(1); ?> seconds.
    		

Do you know or use some other method(s) to optimize the loading time of your blog/website? Don’t forget to share them by commenting.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.twitter.com/vthenerd Vladan

    Great tips! Thank you.

  • http://www.nightocoder.com Rawaf

    Great post, I found some new info for speed My blog
    thank you for share

  • http://vtimbuc.net Valeriu

    When I paste the .htaccess rules for setting up Cache-control header I get a 500 Internal server configuration error.

    • Aditya Jain
      Author

      Where do you host your website?? I mean to know weather it is NGNIX or Apache Server??

    • http://www.mytechguide.org Mezanul

      It’s because of a small mistype in the code.

      Replace >/filesMatch> in line 5 of .htaccess rules for setting up Cache-control header, type </filesMatch>

      • http://wp.envato.com/ Japh Thomson
        Staff

        Thanks, Mezanul! Typo amended ;)

      • Aditya Jain
        Author

        Thanks for notifying :) :)

  • http://mifasm.com Mifas

    Very useful information. Thank you

  • Pingback: Optimizing WordPress Loading Speed With header.php & .htaccess | Qtiva

  • http://skyafar.com/ Ramnadh

    That is great. That for some useful information. My blog is loading much faster.

  • Jesse

    This is amazing! Thank you! Can these methods be used with or in place of a caching plugin?

    • http://fightthecurrent.org Nathaniel

      You definitely want to use these alongside a caching plugin. Every little bit helps =]

      • http://www.thisistg.com JoE

        Any recommended caching plugins?

  • http://www.wpfix.org Wpfix

    Nice tutorial.

  • http://fightthecurrent.org Nathaniel

    Thank you for showing the NGINX equivalents!

  • dan

    Disable ETags? Why?

    • Aditya Jain
      Author

      ETags are constructed using attributes that make them adhere to specific server, ETags won’t match when a browser gets the original component from one server and later tries to validate that component on a different server ; a situation that is all too common on web with growing no. of websites that use a cluster of servers (or sometimes CDN) to handle requests.
      Ultimately instead of small fast 304 response (for which ETags were designed for) there will be much more HTTP Requests & then more response time making your site load slower.
      ETags are fine for static HTML Websites but I think for websites running in Present Continuous (like blogs) eliminating superfluous HTTP requests is a must for decreasing load speed & bits of it can be achieved by disabling ETags.

      I think Enabling ETags on a blog will be like tracing a Mobile Candy Van on a Paper Printed Map in the contrary Disabling Etags on blogs will be tracing it on a GPS tracker & of course GPS must be preferred.

      • juicypx

        This is not completely correct. Of course you’re absolutely right when you say that descreasing HTTP requests is important.
        When you’re hosting your site on a single server you should enable ETag to support cache validation which results in small 304 Not Modified responses from the server instead of 200 OK with the full content – at least when the file has not changed.

        In case you are using a server cluster or CDN you should set FileETag to ‘MTime Size’. Note that the Apache default setting for FileETag is ‘INode MTime Size’. This default setting indeed leads to ETags that are different for every server even if the file is identical. By changing the setting you can still profit from 304 headers even if the file is served from multiple servers.

        Disabling does not decrease load time but can even increase it because the file cannot be validated and has to be downloaded even if it is unchanged. I think that all users should (and are able to) make use of ETags.

  • http://maorchasen.com Maor Chasen

    To switch off post revisions? I don’t think it’s a good idea. It might save up a couple of rows in your posts table, but I’m pretty sure it won’t slows down the site significantly. not even close to that.

  • http://www.elimcmakin.com Eli McMakin

    My combination of CloudFlare and W3TC plugin seems to compress and deliver the content bundled. You can read more about it on my site: http://elimcmakin.com/cloudflare-and-w3tc-not-just-another-cdn-part-i/

  • Pingback: Optimizing WordPress Loading Speed With header.php & .htaccess | Shadowtek Hosting and Design Solutions

  • http://www.jqueryrain.com Sanchit

    Thanks Aditya for this nice post .I like the google’s mod_pagespeed feature for apache.Waiting for other hosting companies implement it on their servers

  • Pingback: WP Engine Announces Download Zip for WordPress Website Backups Summary | Open Knowledge

  • http://www.semidoppel.com Semidoppel

    Thanks for these guides. I have htaccess and probably I’ll check then use the scripts you have mentioned.

  • http://kurswordpress.pl Michał Kalinowski @ Kurs Wordpress

    Great info.
    Do you use any plugins as well to speed up your blog?
    What hosting company are you using?

  • http://simplewpgenius.com Pete

    Thanks Aditya! Great post and in depth… I’ll be sure to make these changes to a few of my blogs

  • http://freakify.com Ahmad Awais

    I use W3TC plugin which already is doing this, my site scores 95/100 on Google Online Page Speed Tool.
    Nice post.

  • Aman P

    Nice Post.
    Hyper Cache was crashing my blog, and I wasn’t able to setup W3 Total Cache. just followed this tutorial (Apache) and my website loading time decreased by 45 % (i took 7 tests)

  • guest

    You didn’t explained why it’s good to disable ETags… I can’t understand that…

  • http://lazaac.com lazaac

    Thanks for nice tutorial.. It helps a lot especially for those using Nginx (like me)..

  • Jay

    I think there is a minor typo in the .htaccess rules for setting up Cache-control header example.

    >/filesMatch>

    should be

    • http://wp.envato.com/ Japh Thomson
      Staff

      Thanks, Jay! All fixed :)

  • http://www.indiastudybuzz.com Sanjeev

    How to find which server i am using Nginx Server or Apache, I am using Netfirms hosting?

    • Aditya Jain
      Author

      I hope you are hosting at netfirms.com
      I had a chat with them and they told that they have Apache Servers.

  • Pingback: Optimizing WordPress Loading Speed With header.php & .htaccess | Wptuts+

  • Chehab

    Thanks for nice tutorial..
    BTW webfaction.com have mod_pagespeed

  • http://www.kevinworthington.com/ Kevin Worthington

    These are some great tips, especially the code for the header.php. Thanks for that!

    A while back I wrote about how to set up a Cookieless Domain, what I equate to a “Poor man’s CDN.” Check it out here:
    http://www.kevinworthington.com/set-cookieless-domain/

    It will speed up your WordPress site. Happy speeding-up!

  • gixty

    Hi, very nice tips. However, I read that it would be best practice to put those commands inside the php.ini file instead of the .htaccess Is this true? If so, how can I adapt your tips inside a php.ini file?

    Thanks!

  • Pingback: HostNine Blog Weekly Round-up: April 30 – May 3 | HostNine Company Blog

  • Pingback: Ottimizza la velocità di caricamento tramite .htaccess e header.php | Wordpress Style

  • Pingback: This Week In WordPress: May 7, 2012 | Max Foundry

  • http://bretglassett.com BretJG

    Thanks for the article. I tested out some of this on a site that wasn’t using any speed/caching plugin :)

  • http://www.iamabdus.com/ Abdus

    Hey Aditya, thanks for sharing. I have applied this to my recent WordPress project and it worked fine.

  • Pingback: Как ускорить загрузку WordPress с помощью header.php и .htaccess | Wordpresso

  • http://silverknightwebstore.com Silver Knight

    Thanks for the info. I’m looking forward giving some of these tip a try.

  • Pingback: Optimizing WP Loading Speed With header.php .htaccess | Wordpress Sifter

  • http://www.1admin.ir masoud

    hi
    thanks for great post.
    but in gtmetrix.com , my ETAGS are misconfigured ?
    its ok or not ?

  • Pingback: Tweet-Parade (no.18 Apr-May 2012) | gonzoblog.nl

  • ivica

    Thank you for advices but what when there isn’t anywhere file .htaccess in WP directory? And it is not issue with the “hidden files”? How can above suggestions be implemented? Thx again!

    • http://carlitoescobar.com Carlito Escobar

      .htaccess file is not a core WordPress file. It’s a directory level configuration file that you can edit to tweak Apache settings if you don’t want to or don’t have access to the core Apache files on your host.

      You can usually create on in the root dir of your site. Here is the WP codex snippet about it: http://codex.wordpress.org/Using_Permalinks#Where.27s_my_.htaccess_file.3F

      c.

  • Pingback: ETagを無効にする .htaccess | WordPressカスタマイズ  My Memo

  • http://vcarvalho.com Vitor Carvalho

    Nginx rules inside .htaccess? Really? For what I know, .htaccess is exclusive for Apache.
    Can you explain a bit more about that configuration?
    Thank you!

  • http://www.eyes4tech.com Arsie

    Thanks for these tips to optimize our websites!

    More power!

  • http://www.digitaladvices.com/ Vivek Nath.R

    Kudos man, after tweaking this my google page speed increases from 90 to 93.
    Thanks a lot.

  • http://www.justofeel.com riyanto justofeel

    thanks for this great post.
    I have applied this to my recent WordPress blog and still waiting for the result.

  • Chris Finiksopoulos

    I may use those for my magento website too??

  • http://blog.radiosabalera.com.ar/ webmaster

    I appreciate the input. I will try … thanks !

    • http://blog.radiosabalera.com.ar webmaster

      Excellent, work fine. Thanks, again

  • http://www.wordpressguru.com.au Wordpress Developer

    This is really good tips. I used this on one of my site and the performance had rocketed. You can use tools like Pingdom Tools to see how your site behaves after the change.

  • Pingback: Speeding up WordPress

  • http://www.geekpy.com Hugo

    Very gread tips! I apply them to my blog :)

  • Pingback: Securing Wordpress - Locking it Down - There is a Theme For That

  • http://www.bloghunk.com Chris

    Adi,

    Thanks for sharing some valuable tips, Actually I was looking for some tips in optimizing my wordpress site without using any Plugin & I’m satisfied this post will help me a lot.

  • Roni

    I host my WP site on Godaddy’s shared server. The .htaccess is in my root directory while the WP installation itself is in a WordPress subdirectory.

    Where in .htaccess file should I place the code you recommended?

    Here is how I pit it using Notepad++ editor (previously I put also in between the BEGIN and END WP lines with same result:

    <IfModule pagespeed_module>
    ModPagespeed on
    # using commands,filters etc
    </IfModule>
    # BEGIN WordPress

    # END WordPress

    I received the following error message:

    Internal Server Error
    The server encountered an internal error or misconfiguration and was unable to complete your request.

    Please contact the server administrator and inform them of the time the error occurred, and anything you might have done that may have caused the error.

    More information about this error may be available in the server error log.

    ——————————————————————————–

    Apache Server at mydomainname.com Port 80

  • ActualTecnologia
  • http://twitter.com/bfintal Jami Intal

    If you’re using a dedicated server, or a cloud server, you can use eAccelerator to further speed up load times.

  • Pingback: Optimization: links & resources | indentity

  • Pingback: Monkee-Boy Blog » 7 Ways to Optimize Wordpress for High Performance

  • Pingback: Is Your WordPress Site’s Speed Affecting Search Rankings | @aseohosting

  • ajkumar25

    Great one dude, keep the good work. http://www.completephotoshop.com

  • http://techbush.com/ Thejas Kamath

    Helped me very much…..http://sayblogger.com

  • Pingback: Lesson Seven Reflection | Nathan's Business Blog

  • http://www.noodweer.be/ Onweer

    nice guide !

  • http://www.facebook.com/mittul.chauhan Mittul Chauhan

    thanks a lott .. i m developer .. but i m always eager to find the seo tips .. nice article..