Search The Hostwinds Guides Knowledge Base

Optimize Website Using .htaccess File

Share This Article [TheChamp-Sharing]

Having your website loading fast is a passion for most Hostwinds clients and we know how important this is. This guide is to help with reviewing your website and it’s load speed so that optimization can be seen and tested by you or your website developer.

We will also explore many options for you to use and common ways to Optimize your website using a .htaccess file. This is intended for shared hosting, business hosting, cPanel clients and VPS, Cloud and Dedicated Server clients who are using Apache web server.

For this guide, we will start out by using Google Chrome’s built in tools and using .htaccess for an Apache web server.

Create .htaccess File

The first thing to do is to create your .htaccess file. Before continuing with this guide, it is important to make a backup of your file to ensure this file can be restored in case your website does not load or you have any issues.

Google Chrome DevTools

#1 Visit your website and launch Google Dev Tools with F12 on Windows or also Ctrl + Shift + I on your keyboard. If you are using a Mac, you can use Cmd + Opt + I. Or, just right click on the web page and select Inspect Element to click on the Network tab

#2 Check the box in disable cache

#3 Click on Network from this same menu and reload the page. Here, the results and load time will show at the bottom of the screen

dev tools load time

Refresh the web page and take note of the load time as shown in the image above. You will also want to take note of the Time To First Byte which would be ideal to be under 200 ms.  The image below shows this as being 120 ms as an example:

time to first byte ttfb

Website Optimization

Utilize Caching

# BEGIN EXPIRES
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 10 days"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/plain "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType application/x-icon "access plus 1 year"
</IfModule>
# END EXPIRES

Compress Content Using Mod Deflate

# COMPRESSION
# BEGIN DEFLATE COMPRESSION
<IfModule mod_deflate.c>
# Compress HTML, CSS, JavaScript, Text, XML and fonts
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
</IfModule>
# END DEFLATE COMPRESSION
# END COMPRESSION

Gzip Compression

# BEGIN GZIP
# BEGIN GZIP COMPRESSION
<IfModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>
# END GZIP COMPRESSION
# END GZIP

Caching

#CACHE CONTROL
# 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
#END CACHE CONTROL

Force Trailing Slash

# FORCE TRAILING SLASH
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} /+[^.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
</IfModule>
# END FORCE TRAILING SLASH

Prevent Hotlinking

# PREVENT HOTLINKING
RewriteEngine On
#Replace ?yourdomainname.com/ with your website url
RewriteCond %{HTTP_REFERER} !^http://(.+.)?yourdomainname.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Replace /images/nohotlink.jpg with your "hotlinking is not permitted" image url
RewriteRule .*.(jpe?g|gif|bmp|png)$ /hotlinksnotpermitted.jpg [L]
# END PREVENT HOTLINKING

Replace yourdomainname with your actual domain name URL and hotlinksnotpermitted.jpg

Redirect Website Visitors to a Mobile Site:

# REDIRECT MOBILE DEVICES
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/m/.*$
RewriteCond %{HTTP_ACCEPT} "text/vnd.wap.wml|application/vnd.wap.xhtml+xml" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "wapp|wapr|webc|winw|winw|xda|xda-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "up.browser|up.link|windowssce|iemobile|mini|mmp" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "symbian|midp|wap|phone|pocket|mobile|pda|psp" [NC]
#------------- The line below excludes the iPad
RewriteCond %{HTTP_USER_AGENT} !^.*iPad.*$
#-------------
RewriteCond %{HTTP_USER_AGENT} !macintosh [NC] #*SEE NOTE BELOW
RewriteRule ^(.*)$ /m/ [L,R=302]
# END REDIRECT MOBILE DEVICES

Stop SPAM On WordPress Blog

# STOP SPAM ON WORDPRESS BLOG
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post.php*
RewriteCond %{HTTP_REFERER} !.*yourdomainname.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]
</IfModule>
# END STOP SPAM ON WORDPRESS BLOG

Replace yourdomainname with your actual domain name URL

Redirect Feeds

# REDIRECT DIFFERENT FEEDS TO A SINGLE FORMAT
<IfModule mod_alias.c>
RedirectMatch 301 /feed/(atom|rdf|rss|rss2)/?$ http://yourdomainname.com/feed/
RedirectMatch 301 /comments/feed/(atom|rdf|rss|rss2)/?$ http://yourdomainname.com/comments/feed/
</IfModule>
# END REDIRECT DIFFERENT FEEDS TO A SINGLE FORMAT

Replace yourdomainname with your actual domain name URL

Configure Your Website for HTML5 Videos

# CONFIGURE YOUR WEBSITE FOR HTML5 VIDEOS
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
AddType video/ogg .ogv
AddType video/ogg .ogg
AddType video/mp4 .mp4
AddType video/webm .webm
AddType application/x-shockwave-flash swf
# END CONFIGURE YOUR WEBSITE FOR HTML5 VIDEOS

Log PHP Errors Into An Error Log

# LOG PHP errors INTO ~/public_html/php_error.log
# display no errs to user
php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
# log to file
php_flag log_errors on
php_value error_log ~/public_html/php_error.log
# END LOG PHP errors INTO ~/public_html/php_error.log

Replace yourdomainname with your actual domain name URL and ~/public_html/php_error.log with the location of your log file

Run PHP Inside JavaScript Files

# RUN PHP INSIDE JAVASCRIPT FILES
AddType application/x-httpd-php .js
AddHandler x-httpd-php5 .js
<FilesMatch ".(js|php)$">
SetHandler application/x-httpd-php
</FilesMatch>
# RUN PHP INSIDE JAVASCRIPT FILES

Block User IPs

#BLOCKING USERS IP
order allow,deny
deny from 123.45.6.7
deny from 0.1.2.3
allow from all
#END BLOCKING USERS IP

Replace 123.45.6.7 and 0.1.2.3 with the actual IP addresses you want to block

Prevent Directory Listing of Files

#PREVENT DIRECTORY LISTING
IndexIgnore *
#END PREVENT DIRECTORY LISTING

Custom Error Document

# ERROR DOCUMENT
ErrorDocument code /directory/filename.ext
ErrorDocument 404 /errors/lostandfound.html
# END ERROR DOCUMENT

Replace /directory/filename.ext with the error document you would like to use and /errors/lostandfound.html with the 404 error page you would like to use to replace the default error documents

Redirect Non WWW URL to WWW URL

# REDIRECT NON WWW URL TO WWW URL
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^yourdomainname.com
RewriteRule (.*) https://www.yourdomainname.com/$1 [R=301,L]
# END REDIRECT NON WWW URL TO WWW URL

Replace yourdomainname in three places, /olddirectory/oldfile.html with the old file name and newfile.html with the new file name

Simple Redirect

# SIMPLE REDIRECT
Redirect /olddirectory/oldfile.html https://yourdomainname.com/newfile.html
# END SIMPLE REDIRECT

Replace /olddirectory/oldfile.html and https://yourdomainname.com/newfile.html

Redirect Website to https 

#Force SSL without www
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourdomain.tld/$1 [R,L]
#Force SSL with www
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.tld/$1 [R,L]

Replace yourdomain.tld with your actual domain name

Related Resources