PageSpeed Insights and Ghost - Part 1

I went to Google's PageSpeed Insights page the other day to check my score. I am currently using the default Casper theme for my Ghost blog. My baseline score for Mobile was 74/100 and on Desktop 82/100. These scores aren't bad but I know I could get it a lot higher. The goal, of course, is to end up with a perfect 100/100.

Later this month ( April 21, 2015 ), Google will be updating their search algorithm and promoting pages that have better performance especially on mobile devices. This is a good time to make the changes that we need to before they impact rankings.

What PageSpeed checks

Here are the items that are being tested:

  • Avoid landing page redirects
  • Enable compression
  • Minify HTML
  • Minify JavaScript
  • Minify CSS
  • Optimize images
  • Prioritize visible content
  • Reduce server response time
  • Eliminate render-blocking JavaScript and CSS in above-the-fold content
  • Leverage browser caching

There is some good news (for me at least). A couple of these are already optimized: Avoid landing page redirects and Minify HTML. That still gives us plenty to do. In this article, I am going to concentrate on what I can do on my server to help the score. In a follow up article, go over how I modified the default theme.

Off we go!

Configuring Nginx

On my host, Nginx routes traffic to my Ghost blog. But, by default, the server configuration isn't as optimal as it could be. We are going to knock out two metrics: Leverage browser caching and Enable compression. To do this we will have to change Nginx's configuration files. For browser caching we need /etc/nginx/conf.d/default.conf and /etc/nginx/nginx.conf for gzip compression.

Enabling GZIP compression

By enabling GZIP compression on the server, web browsers can download the files faster. This kind of compression results in a file size reduction of 50% - 70%. And that will give us an overall increased page speed.

On the server in the /etc/nginx find the nginx.conf and add the following code into the http{ } area of the file. I put mine at the very top of this section and it looks like this:

http {
 gzip on;
 gzip_comp_level    5;
 gzip_min_length    256;
 gzip_proxied       any;
 gzip_vary          on;
 gzip_types
   application/atom+xml
   application/javascript
   application/json
   application/ld+json
   application/manifest+json
   application/rdf+xml
   application/rss+xml
   application/schema+json
   application/vnd.geo+json
   application/vnd.ms-fontobject
   application/x-font-ttf
   application/x-javascript
   application/x-web-app-manifest+json
   application/xhtml+xml
   application/xml
   font/eot
   font/opentype
   image/bmp
   image/svg+xml
   image/vnd.microsoft.icon
   image/x-icon
   text/cache-manifest
   text/css
   text/javascript
   text/plain
   text/vcard
   text/vnd.rim.location.xloc
   text/vtt
   text/x-component
   text/x-cross-domain-policy
   text/xml;

# -- REST OF THE FILE HERE!!     

That should give us a good setup for the compression. Now let's set up some expires headers by modifying the default.conf file. If you want you can restart Nginx ( see below for the command to execute on the server ). This will add these changes and verify that there are no typos, etc. Or you can just go ahead and move to the next section.

Configuring Cache-Control & Expires header

I'm not going to go into why this is a good thing here. Other smarter people can explain it much better than I can. Basically, the longer files are in cache the better the performance of the site. You can always bust the cache when you make a change. The default cache time is one hour which is terrible from a performance perspective. So I wanted to make mine last for a much longer time. For Ghost and Nginx, we change the default.conf file located in the etx/nginx/conf.d/ folder.

Here is that file:

server { 
  listen 80; 
  server_name YOURDOMAINNAMEHERE; #replace with your domain

  # Theme assets (CSS, Javascript) 
  # Cache these assets for 30 days

  location /assets/ { 
    expires 30d; 
    add_header Pragma public; 
    add_header Cache-Control "public"; 
    proxy_pass http://localhost:2368/assets/; 
    proxy_set_header Host $host; proxy_buffering off; 
  } 


  # jQuery (and other vendor files)
  # Cache these assets for 365 days!!

  location /public/ { 
    expires 365d; 
    add_header Pragma public; 
    add_header Cache-Control "public"; 
    proxy_pass http://localhost:2368/public/; 
    proxy_set_header Host $host; 
    proxy_buffering off; 
  } 


  # Everything else

  location / { 
    proxy_pass http://localhost:2368/; 
    proxy_set_header Host $host; 
    proxy_buffering off; 
  } 
}

Now, everything in our theme assets folder will stay in cache for thirty days. For those in the public folder (for jquery ), it will stay for 365 days!

We need to restart Nginx for these changes to go into effect.

[sudo] service restart nginx

Once I rerun the PageSpeed tests, four our of our ten tests passed! Our score has gotten higher as well.

Google PageSpeed Score

Now, we have taken care of the server configuration. We can start working on customizing the Casper theme. This will be where we will do the majority of our work.

I will do that in another post.
Updated: Part 2 is up!

'Til next time!
-G