Setting up PageSpeed Insights to test Performance Locally via Gulp

December 17, 2014

Listen to this blog post:
Your browser does not support the audio element.

Today, I’ll be walking you through setting up PageSpeed Insights within your existing gulp project. This way, each time you call gulp psi in your terminal, you can get your page speed insights scores right in your terminal without needing to push your site to a live server, navigate to the PageSpeed Insights website, enter in your URL, etc. I’ll be using ngrok to tunnel your locally hosted site and a few gulp tasks to bring it all together.

PageSpeed Insights

PageSpeed Insights is a project by Google that analyzes the performance of your website, giving you a score index based on a variety of factors. Addy Osmani created a neat little node module so that we can run PageSpeed insights right in the terminal and get a nicely formated table of scores.

To install this tool globally (which I recommend, because you can use it with any live website, any time), simply type npm install -g psi into your terminal.

The way it works is simple: merely type psi http://example.com in your terminal. For instance, if try google.com, it will give you this:

Unfortunately, PageSpeed Insights (psi) doesn’t work on locally hosted websites. So, if you try running psi http://localhost:3000 it won’t work. But that’s okay. There are brilliant people on the internet who have developed solutions for us. Enter ngrok!

Testing Locally with Ngrok

I shamelessly stole this infographic from ngrok's website.

Ngrok is a pay-what-you-want service that allows users to try out a web site they’re developing without deploying it to the internet. There is a paid tier, but you don’t need to sign up for an account in order to get PageSpeed Insights working locally. You can download ngrok with a binary or via npm:

npm install -g ngrok

Now, depending on what server you’re running gulp on, type ngrok http <port> into your terminal. Since I’m using port 3000, I’ll use ngrok http 3000. Then you should see something like this:

That Forwarding URL is what we’ll use to get our page speed insights. Try it now. Type psi <your forwarding url> and you should see a response!
Pretty cool right?

Keep in mind that this may take a few moments, and you do need to be on an internet connection

Pulling it together with Gulp

Install Dependancies

In order to set this up in our development environment, we’ll be using three modules: ngrok, psi, and run-sequence. (and gulp-exit to close out of everything) You can install them all at once, while saving the dependancies to your package.json in one command:

npm install psi ngrok run-sequence gulp-exit --save-dev

Alternatively, you can open up your package.json, and under ‘devDependancies”, add the following lines of code:

If you’re using an API key, be sure to replace the nokey: 'true' line with your key: <your API token here>.

Almost there

Now, everything is almost ready. The only problem is that we need to link the tunnel url that ngrok is creating for us to psi. For this, we’re using the run-sequence module to alow variables to pass between in between asynchronous tasks.

We’ve only got two more variables to set up.

var sequence = require('run-sequence');
var site = '';

Now, we can create a sequence to run the ngrok tunnel server, grab its url, and run page speed insights tests for both desktop and mobile.

So at this point, if you have a server running at port 3000, and run gulp psi in another terminal window, it should give you accurate results. But let’s improve on that. Let’s make a self-contained gulp task that doesn’t depend on another.

Servers, Ports, and Tasks, oh my!

To do that, we need to connect ngrok to our server. Now, I’m not going to dictate how you start your server. Personally, I really like using Browser Sync for a variety of reasons. A simple Gulp Connect task also exists. Whichever way you do it, add the task in which you’re starting your server before the ngrok-url task in your psi sequence. For example, mine, with brower sync, is:

BrowserSync is really cool in the sense that if a port is taken (i.e. if port:3000 is busy), it will use the next available one (i.e. port: 3001). This can cause issues if you aren’t cognicant of it and may be running multiple development environments at once. Well, what will likely happen is you’ll just get a false 100 in return for your page score value.

Because we’re specifying the port here, we have to make sure that it is available to avoid those faulty scores. To improve this a bit, I set up a separate BrowserSync function seperate from my development task, specifically PageSpeed Insights. This got rid of some of the excess (watch tasks, etc), and I also gave it some more configs like not opening the page in the browser every time I just want to test performance.