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

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:

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