How to get a high score on Pagespeed Insights (and make your site fast)

This post is about how to optimize your page for speed and we’re going to test the results with the Pagespeed Insights tool provided by Google.

Google started weighting results on their search engine result pages after the results for your website, so if you score high numbers, you are more likely to show up, especially for mobile users.

TL;DR

The faster your website is to load at first, the more likely Google is to score you higher in the search results (because you seem to give a shit about your users experience). Modify your web server configuration and web application code to make your site fast and usable on mobile.

Below I’ll describe the tools we used, you don’t have to use the same, but you can take inspiration from what we’re trying to do with them.

Pagespeed Insights Criteria

These are the criteria that Google scores your page after, you can have a closer look at them and what Google recommends you do to make your site faster on the Pagespeed Insights site after entering a URL.

  • Avoid landing page redirects
  • Avoid plugins
  • Configure the viewport
  • Eliminate render-blocking JavaScript and CSS in above-the-fold content
  • Enable compression
  • Leverage browser caching
  • Minify CSS
  • Minify HTML
  • Minify JavaScript
  • Optimize images
  • Prioritize visible content
  • Reduce server response time
  • Size content to viewport
  • Size tap targets appropriately
  • Use legible font sizes

Our case: A Photography Portfolio

My girlfriend and I started a small photo studio together in our living room which we called GegenWind We both have a passion for photography and wanted to tell people about it, because we both have our own photo projects going. We decided we probably would work well as a team and started working on the website. Since we both know how to code HTML and CSS, we went for a static site, but you can achieve similar and better results using a CMS like WordPress or rolling your own.

gegenwind-photography

Tools for Automation and Page Speed

We used the following tools so we wouldn’t have to write every single line of code ourselves:

  1. Gulp, a JavaScript task runner that automates a bunch of things for us
  2. Handlebars, a templating engine, because frankly most of our portfolio pages look the same, they just have different images
  3. SASS, a CSS preprocessor that allows us to write less repetitive CSS
  4. Git and GitLab, a version control system that let us both code individually on the website and took care of melting our code together.

Gulp

gulp-pagespeed

Gulp is a JavaScript task runner, which we use to automate the following things:

  • compiling handlebars templates to HTML
  • inserting data into handlebars templates
  • compiling SASS to CSS
  • optimizing images in resolution and file size

Gulp pretty much just sits on the command line while you code and takes care of stuff for you, that you would have to do manually. Don’t be afraid of the terminal, it will save you a ton of work in the end.

Gulp GM (GraphicsMagick) & Imagemin

pagespeed-optimized-image-size

Related Pagespeed Insights rule: Optimize images.
These are two of the more important Gulp Plugins covered, gulp-gm and gulp-imagemin. You don’t need to use Gulp for resizing and optimizing your images, but it certainly helps that it’s done automatically across dozens of images at a time.

One of the Pagespeed Insight recommendations is that you serve images at the resolution they’re being displayed at to avoid unnecessary load times for users whose displays wouldn’t be able to show such a high resolution image anyways.

The raw CR2 files from our cameras are 24MB each, at full resolution and quality a JPG is around 10MB, the images we display to our users at 1080×1080 are between 100KB and 400KB. File size is important because both low bandwidth mobile users or older/weaker smartphones will have trouble displaying large images quickly and have the page scroll without jittering.

Handlebars

Related Pagespeed rule: Configure the viewport.

This part of our tool chain actually is not very relevant for the speed, since it just compiles the templates to HTML. No fancy magic, it just saves us repetitive work, which we then can use to take more photos. Win-Win.

An example of where the templates were really useful is, that we wanted a “get in touch” button at the bottom of every portfolio page. If somebody actually looks at all the images in a category, it seems logical to offer them to have a chat with us.

file: street.hbs:

<div class="content">
  <div class="featured portfolio-items">
    {{#each dataPortfolio.street}}
      <img class="{{this.class}}" src="images/{{this.image}}">
    {{/each}}
  </div>
</div>

{{> footer}}

file: footer.hbs

<a href="about.html" id="getInTouch">Get in Touch!</a>
<script async type="text/javascript" src="js/main.js"></script>
<div id="footer">&copy; {{currentYear}} Judith K&ouml;thnig &amp; Jonathan M. Hethey </div>

This means that the {{> footer}} partial will be injected into each page.

Regarding the viewport rule, we have the following, important line in our header that makes our site much easier to style for and handle for mobile devices, since we define how the viewport there should work:

<meta name="viewport" content="width=device-width, initial-scale=1">

Asynchronous CSS loading with JavaScript

Also placed in the footer is a small snipped of JavaScript that basically first loads the CSS file from Google Webfonts when the JavaScript on the page is executed, which is after the browser is done showing stuff for the first time. Remember, you want to get your content out there, what font it’s in might not be the ultimate question for your readers/viewers.

This by the way is one of the more important techniques in order to get rid of warnings regarding Eliminate render-blocking JavaScript and CSS in above-the-fold content from the Pagespeed Insights test.

The following is in our footer in a <script> tag:

var cb = function() {
  var h = document.getElementsByTagName('head')[0];
  var k = document.createElement('link'); k.rel = 'stylesheet';
  k.href = 'https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700';
  h.parentNode.insertBefore(k, h);
  };

  var raf = requestAnimationFrame || mozRequestAnimationFrame ||
    webkitRequestAnimationFrame || msRequestAnimationFrame;
  if (raf) raf(cb);
  else window.addEventListener('load', cb);

SASS

Related pagespeed rules: Size tap targets appropriately, Use legible font sizes.

This again is not a crucial part, but it makes styling for mobile user experiences a little easier. You can utilize the mixins and variables to make sure you always use the correct font colour or mobile breakpoint when coding together.

Here’s a quick example of the variables:

$font-family: 'Open Sans', sans-serif;
$bgcolor: #EBEDED;

body {
  background-color: $bgcolor;
  margin: 0;
  font-size: 100%;
}

For the related rules: Basically don’t make stuff unreadable on phones and don’t make buttons too hard to hit on mobile.

Git and GitLab

gitlab-history

This part again isn’t very much related to how to make your page fast, but on a higher level it made us actually collaborate. We had to think about if what we did would make sense to the other and actually it’s very encouraging to not do something alone. Git is something you should learn right away if you’re pursuing a career in development. GitLab is a great and free service where you can host your git repositories (projects), so we got a nice overview of what we did when and had the possibility to easily sync each others steps across our computers.

gitlab-commits

Nginx Server Configuration for Compression

Related Google Pagespeed Insights rule: Enable compression, Leverage browser caching.

I’m using Nginx as a webserver for most of my PHP and Node.js projects, so it’s used for this page too.

In the general nginx.conf I have specified some gzip namespaced rules that handle most of the compression aspects.

gzip  on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

Below is the caching setting for which files are not likely to change within 7 days, it basically tells the browser: You’ve gotten that image before, now leave me alone and just use the saved copy you have and show it to your user.

location / {
  root /var/www/gegenwind.dk/;
  if ($request_uri ~* ".(jpg|jpeg|gif|png)(\?v=[0-9.]+)?$") {
    expires 7d;
    break;
  }
}

If you’re on a shared web space, you might have limited influence on how your web server is set up. I tend to use Digital Ocean for a lot of my projects, where you have a great interface and a lot of Linux images available to start your web projects.

If you’re looking for another host, I can also recommend Linode for their fairly low priced VPS.

Summary: most important for loading speed / pagespeed / mobile Website speed

Basically the entire process of speeding up your site is not very mystical. For the most part it’s just to make sure especially mobile users feel welcome and that they get to see what they come to your page for rather quickly. Imagine you didn’t have the most recent iPhone, but that you are stranded on an island and you have an edge connection, you still really need to hit that emergency coastguard website without first loading a large flash player, multiple embeds or something you really don’t see as a priority right now.

Use JavaScript wisely to load content WHEN the user needs it, like lazy loading images or CSS files.

Thank you for reading! I would love to hear from you what measures you take to make your site just a little bit faster and push your site performance a little further!

I hope I could give some insights into how we got away with a not too bad score, even though we have tons of pictures on the site.

Leave a Reply

Your email address will not be published. Required fields are marked *