This is the second post in our series about performance budgets. In the first one Add performance budgets to your CI we talked about the bundle size. We explained how important it is to measure, optimize, and monitor if you are to get fast and stay fast. We stated that performance plays a significant role in the success of any online venture.

In this blog post we will show you how easy it is to run Lighthouse inside your Continuous Integration and to keep an eye on the audits for Performance, Accessibility, Best Practices and SEO (Search Engine Optimization). Other implementations require ngrok, ssh tunnels, extra third party tools, temporary hosting providers, other complicated setup processes or only work with a single CI solution.

First of all make sure the whole setup works on your local machine. Start the create-react-app development server.

$ npm run start

Then in another terminal install and start Lighthouse to show the results.

$ npm install --save-dev lighthouse $ npx lighthouse http://localhost:3000 --view

Here is a screenshot of the HTML output from my local machine.

The HTML output is great for local development but not so great for machine analysis during Continuous Integration. Inside your Continuous Integration you need to have access to the raw data. So instead of using HTML as the output use JSON. You also have to specify the output path by setting --output-path=./lighthouse.json . Last but not least tell Chrome to run in headless mode, i.e. without a UI or display server dependencies.

npx lighthouse http://localhost:3000 \ --output json \ --output-path = ./lighthouse.json \ --chrome-flags = "--headless"

The lighthouse.json file contains a lot of information but the most relevant part starts at the categories key. There we have our categories Performance, Accessibility, Best Practices, SEO and PWA.

"categories" : { "performance" : { "title" : "Performance" , "id" : "performance" , "score" : 0.78 } , "accessibility" : { "title" : "Accessibility" , "id" : "accessibility" , "score" : 0.94 } , "best-practices" : { "title" : "Best Practices" , "id" : "best-practices" , "score" : 0.93 } , "seo" : { "title" : "SEO" , "id" : "seo" , "score" : 0.92 } , "pwa" : { "title" : "Progressive Web App" , "id" : "pwa" , "score" : 0.67 } }

The score value is always between 0 and 1 so to calculate the percentage simply multiply it by 100. I have also added the unit % to the output to make sure seriesci can show it in the badges and charts. Use node to process the JSON via the command line. You could also use a different tool like jq but since node is already available during our Continuous Integration we are using this solution.

node -p "require('./lighthouse.json').categories.performance.score * 100 + '%'"

Inside our CI we do not want to start the development server just to serve the app for Lighthouse. Instead build the app with npm run build and serve the static files using Python. This way we can simply send the server process to the background by appending & .

npm run build cd build python3 -m http.server &

In the end combine all of the scripts previously described and you are done adding Lighthouse audits to your Continuous Integration. The following YAML works with CircleCI but all of the other CI providers should work similarly.

- run : name : Add lighthouse audits to seriesci command : | npm run build cd build python3 -m http.server & npx lighthouse http://localhost:8000 --output json --output-path=./lighthouse.json --chrome-flags="--headless" node -p "require('./lighthouse.json').categories.performance.score * 100 + '%'" | xargs -I {} curl \ --header "Authorization: Token ${TOKEN}" \ --data-urlencode value="{}" \ --data sha="${CIRCLE_SHA1}" \ https://seriesci.com/api/repos/seriesci/cra/performance/combined

Now everything is in place and all your metrics are being updated on every commit.

Check out the live demo at GitHub github.com/seriesci/cra and at seriesci seriesci.com/seriesci/cra. Start adding Lighthouse audits to your application by installing the seriesci GitHub app for your repository. It is free for open source and easy to integrate.