How do I reduce my redirect chain and time to first byte (TTFB)?

July 22, 2018 1.7k views
Initial Server Setup Server Optimization Networking LAMP Stack Apache MariaDB PHP DNS VPN Ubuntu 16.04

If I enter example.com in my address bar, the redirect for my server will look like this:

example.com -> http://www.example.com/ -> https://www.example.com/ -> https://www.example.com/en/

I know that I could cut down at least one redirect by changing from www.domain.com back to .domain.com but that really is the last resort since it is a tradeoff between the perceived profesionalism of the website and its performance.

For most of my speed tests I entered https://www.example.com/en/ to not get penaltalized for the redirects only to notice that the time to first byte is terrific with 1.5 - 4 seconds depending on the server's location.

At first I was under the impression that I simply had misconfigured the servers but after finally just entering example.com in any of the TTFB tests, I got anything from 24ms in frankfurt to 620ms in sydney.

My ssl redirects are based on the Let's encrypt force ssl and my language related redirects are based on the CMS I'm using. The www redirect is domain based and the CMS is also set to run on www.domain.com rather than domain.com.

My question now is, is there a way to reduce the redirect chains or to modify them in a way to be less taxing on the TTFB?

This is the content of my .htaccess

<IfModule mod_rewrite.c>
<IfModule mod_env.c>
SetEnv HTTP_MOD_REWRITE On
</IfModule>

RewriteEngine on


#Domain: www.example.com
RewriteRule . - [E=REWRITEBASE:/]
RewriteRule ^api$ api/ [L]

RewriteRule ^api/(.*)$ %{ENV:REWRITEBASE}webservice/dispatcher.php?url=$1 [QSA,L]

# Images
RewriteRule ^([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$1$2$3.jpg [L]
RewriteRule ^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$1$2$3$4.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$1$2$3$4$5.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg [L]
RewriteRule ^c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2$3.jpg [L]
RewriteRule ^c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2.jpg [L]
# AlphaImageLoader for IE and fancybox
RewriteRule ^images_ie/?([^/]+)\.(jpe?g|png|gif)$ js/jquery/plugins/fancybox/images/$1.$2 [L]

# Dispatcher
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ %{ENV:REWRITEBASE}index.php [NC,L]
</IfModule>

AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType application/font-woff .woff
AddType font/woff2 .woff2
<IfModule mod_headers.c>
    <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|svg)$">
        Header set Access-Control-Allow-Origin "*"
    </FilesMatch>
</IfModule>

<IfModule mod_expires.c>
    ExpiresActive On
    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 week"
    ExpiresByType text/javascript "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType application/x-javascript "access plus 1 week"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
    ExpiresByType application/font-woff "access plus 1 year"
    ExpiresByType application/x-font-woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
    ExpiresByType font/opentype "access plus 1 year"
    ExpiresByType font/ttf "access plus 1 year"
    ExpiresByType font/otf "access plus 1 year"
    ExpiresByType application/x-font-ttf "access plus 1 year"
    ExpiresByType application/x-font-otf "access plus 1 year"
</IfModule>

<IfModule mod_headers.c>
    Header unset Etag
</IfModule>
FileETag none
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/x-javascript font/ttf application/x-font-ttf font/otf application/x-font-otf font/opentype image/svg+xml
    </IfModule>
</IfModule>

#If rewrite mod isn't enabled
ErrorDocument 404 /index.php?controller=404
2 comments
  • I would switch to nginx. Is that an option for you?

  • The best I could see myself doing would be to use nginx infront of apache but I can't quite follow on how this would reduce the redirect chain. Or are we solely talking about the time to first byte here?

2 Answers

HSTS preloading could load the ssl version locally by default in chrome/firefox.

  • Thank you for suggesting this. I've requested to be included in HSTS and activated it in cloudflare aswell. I furthermore decided to drop the www.

    So as of now the redirect is example.com -> https://example.com/ -> https://example.com/en/

    The first redirect will drop for the browsers that support HSTS preloading. I guess that is as good as it gets.

Yea with HSTS preloading you will only have 1 redirect which should be quite fast but then again if the end url is //example.com/en/ then search engines and such will index that one so there will only be need for a redirect in case the user decides to manually input the url which doesn't happen as much these days since browsers do cache URLs as well.

  • I agree with that. This ultimately was part of the reason as to why I decided to drop the www. as "professional" as it might look to certain people's eyes, it's not like anyone bothers to type it out anyways.

    I'll still look into the NGINX infront of apache solution mentioned above. Even though I have my doubts that setting this up on the same droplet would be all that beneficial. At the end of the day it's the start of a small project.

    • Nothing wrong with testing it out even if it's only a small increase in performance. The project might be small now but you never know how things turn out after a while.

Have another answer? Share your knowledge.