Page speedTop

If you wonder why this site loads so fast, here is the answer.

This page is really small and does not use huge frameworks like Bootstrap or jQuery. If you block the Piwik requests (e.g. with Ghostery) it needs only 2 requests – without pictures. Apart from Piwik, it does not use JavaScript at all.

I use a heavily modified version of Pico CMS. It generates the pages from Markdown files. With its caching mechanism its more like a static site generator than a CMS. For performance reasons I got rid of Twig (PHP does the templating stuff much better) and Composer (I’m well aware of what classes I want to use…).

Enable compressionTop

In the .htaccess file (sorry, no solution for nginx):

<IfModule mod_deflate.c>
  AddOutputFilter DEFLATE js css woff woff2
  AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/xml application/x-font-woff application/font-woff2
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

Set expires headersTop

<IfModule mod_headers.c>
  <FilesMatch "\\.(ico|jpe?g|png|gif|swf|woff)$">
    Header set Cache-Control "max-age=31536000, public"
  <FilesMatch "\\.(css)$">
    Header set Cache-Control "max-age=2692000, public"
  <FilesMatch "\\.(js)$">
    Header set Cache-Control "max-age=2692000, private"
  <FilesMatch "\.(js|css|xml|gz)$">
    Header append Vary: Accept-Encoding
  Header unset ETag
  Header append Cache-Control "public"

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType image/x-icon "access plus 1 year"
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType text/javascript "access plus 1 month"
  ExpiresByType application/octet-stream "access plus 1 month"
  ExpiresByType application/x-javascript "access plus 1 month"


Every served file is minified, i.e. unnecessary whitespace is removed.

To minify CSS:

function minifyCss($css)
  return trim(preg_replace(
    array('/^\s+/m', '/\s+$/m', '/([\n\r]+ *[\n\r]+)+/', '/[ \t]+/', 
      '/[ \n]+/', '!/\*[^*]*\*+([^/][^*]*\*+)*/!'),
    array('', '', " ", ' ', " ", ""),

To minify HTML (found somewhere):

function minifyHtml($text)
  ini_set("pcre.recursion_limit", "16777");  // 8MB stack. *nix
  $re = '%# Collapse whitespace everywhere but in blacklisted elements.
      (?>             # Match all whitespans other than single space.
        [^\S ]\s*     # Either one [\t\r\n\f\v] and zero or more ws,
      | \s{2,}        # or two or more consecutive-any-whitespace.
      ) # Note: The remaining regex consumes no text at all...
      (?=             # Ensure we are not in a blacklist tag.
        [^<]*+        # Either zero or more non-"<" {normal*}
        (?:           # Begin {(special normal*)*} construct
          <           # or a < starting a non-blacklist tag.
          [^<]*+      # more non-"<" {normal*}
        )*+           # Finish "unrolling-the-loop"
        (?:           # Begin alternation group.
          <           # Either a blacklist start tag.
        | \z          # or end of file.
        )             # End alternation group.
      )  # If we made it here, we are not in a blacklist tag.
  $pos = strpos($text, "<html");
  if ($pos)
    // skip everything before <html>
    $header = substr($text, 0, $pos);
    $toMinify = substr($text, $pos);
    $header = "";
    $toMinify = $text;
  $toMinify = preg_replace($re, " ", $toMinify);
  if ($toMinify === null) 
    exit("PCRE Error! File too big.\n");
  return $header . $toMinify;

Sorry, no solution for JavaScript.



I have no clue why YSlow suggests to use CDNs, because most of the time this does not make the site faster, but slower. Not to mention the security risks, since you have no control of what is served, and privacy issues. Some reasons why:

Timing for the first request (Waiting means the response is prepared, i.e. the server is working, PHP code is executed etc.):

HTTP timing

Timing for the second request, you see that DNS resolution and Connecting is not required:

HTTP timing

For this example DNS resolution plus connecting needs almost the same time as generating the response.

So, using a CDN seems to be one of the worst ideas when loading time is important.

Last GTmetrix reportTop