All the details are from Lighthouse conference guide (at the README file)
- Introduction
- Base Audits
- Getting Started
- Writing Your Own Audit
- Using Lighthouse Programmatically
- Testing with Lighthouse example
- Continues Integrations
Automated checks for Progressive Web Apps.
- PWA checklist: (highlights).
- Loading time for 3G
- Using service worker
- Respond with a 200 when offline (should we do that?)
- Prompting to users to add the app to their home-screen
- Configure for a custom splash screen
- Fetch a Manifest
- Size correctly for the viewport
- Redirect HTTP traffic to HTTPS
- Best Practices: (highlights)
- Using HTTP/2 for all of its resources
- Using passive listeners to improve scrolling performance
- Don't use
document.write()
- Not logging to console browser errors
- Performance measuring: (highlights).
Divides to real user experiences:
- FP - First Paint - the first non-blank paint on screen
- FCP - First Contentful Paint - Navigation has successfully started
- FMP - First Meaningful Paint - Page's primary content is visible
- TTI - Time To Interactive - Visually usable and engagable
Moreover, more indications for performance increasing by minified javascript files for example.
- Accessibility: (highlights)
- Unique
id
attributes - Page specifies valid language (
<html>
element should have alang
attribute) <frame>
and<iframe>
elements should have a title- Buttons should have an accessible names
installation with:
npm i -g lighthouse
Run with:
lighthouse http://localhost:8080
Useful CLI flags:
--view
For the chrome dev-tools audits tab--output
choose output scheme ('json' / 'html' / 'csv' - default 'html')--output=json
--output-path
output to file--output-path=./report.json
--extra-headers
set extra HTTP headers to pass with request--extra-headers=./path/to/file.json
Issue with solution for extra headers: GoogleChrome/lighthouse#5085--emulated-form-factor
device form factor. default for mobile.--emulated-form-factor=desktop
You can write your own lighthouse plugin:
Assume you have set a global variable like siteMetrics
, with attributes on it.
For example, interactiveTime
and you've set it to X
time after your content is loaded.
- Create a
Gatherer
to collect info
const Gatherer = require('lighthouse').Gatherer
class SiteMetricsGatherer extents Gatherer {
beforePass() {
// before page loads
}
afterPass(options) {
const driver = options.driver
return driver.evaluateAsync('window.siteMetrics') // Runs this javascript snippet in the context of the page
}
}
module.exports = SiteMetricsGatherer
- Create an
Audit
to verify metrics
const Audit = require('lighthouse').Audit
class LoadAudit extents Audit {
static get meta() {
return {
category: 'CustomThing',
name: 'load-audit',
description: 'Site is loaded and ready',
requiredArtifacts: ['SiteMetricsGatherer']
}
}
static audit(artifacts) {
const interactiveTime = artifacts.SiteMetricsGatherer.interactiveTime
return {
rawValue: `${interactiveTime} ms`,
score: interactiveTime <= 4000 //your threshold
}
}
}
module.exports = LoadAudit
- Create a
Config
to run them
custom-config.js
:
module.exports = {
extends: 'lighthouse:default', // take all the default from lighthouse
passes: [{
passName: 'defaultPass',
gatherers: ['site-metrics-gatherer']
}],
audits: ['load-audit'],
categories: { // category in dev-tools audits tab
mysite: {
name: 'My site metrics',
description: 'Metrics for our site',
audits: [{id: 'load-audit', weight: 1}]
}
}
}
When you've finished, just run audits, and your new category would appear at Audits!
If you would like to run only your custom audit, run:
lighthouse \ --config-path=custom-config.js \ http://localhost:8080 --view
You can view the whole guide here.
const Lighthouse = require('lighthouse')
const ChromeLauncher = require('chrome-launcher')
async function launchChromeAndRunLighthouse(url, flags, config = null) {
const chrome = await ChromeLauncher.launch()
flags.post = chrome.exports
const results = await Lighthouse(url, flags, config)
await chrome.kill()
return results
}
launchChromeAndRunLighthouse('https://example.com', {output: 'json'})
.then(results => {
// use results
})
Example of my own testing for a lighthouse scoring by categories:
Config file:
module.exports = {
CATEGORIES: {
pwa: {
CURRENT_SCORE: 0.2
},
accessibility: {
CURRENT_SCORE: 0.5
},
performance: {
CURRENT_SCORE: 0.15
},
seo: {
CURRENT_SCORE: 0.6
}
},
URL: 'https://example.com'
}
Test file:
'use strict'
const _ = require('lodash')
const lighthouse = require('lighthouse')
const chromeLauncher = require('chrome-launcher')
const lighthouseMeasuring = require('./lighthouseMeasuringConfig')
function launchChromeAndRunLighthouse(url, opts, config = null) {
return chromeLauncher.launch({chromeFlags: opts.chromeFlags}).then(chrome => {
opts.port = chrome.port
return lighthouse(url, opts, config).then(results => chrome.kill().then(() => results.lhr))
})
}
describe('lighthouse', function () {
let results = null
beforeAll(function () {
this.origTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30 * 1000
})
afterAll(function () {
jasmine.DEFAULT_TIMEOUT_INTERVAL = this.origTimeout
})
describe('measuring blank template', function () {
beforeAll(async function () {
results = await launchChromeAndRunLighthouse(lighthouseMeasuring.URL, {
output: 'json',
extraHeaders: lighthouseMeasuring.SESSION_HEADER,
chromeFlags: ['--headless'],
emulatedFormFactor: 'desktop'
})
})
_.forOwn(lighthouseMeasuring.CATEGORIES, (category, categoryName) => {
describe(`${category} score`, function () {
it('should be bigger than current score', async () => {
const score = results.categories[categoryName].score
expect(score).not.toBeLessThan(category.CURRENT_SCORE)
})
})
})
})
})
The example is used with Travis
:
language: node_js
script:
- npm run lint
- npm run build
after_success:
- './travis/deploy_pr_gae.sh' // will vary based on your setup
- export LH_MIN_PASS_SCORE=96
- export LH_TEST_URL=https://your.staging.server.com/
- node travis/runLighthouse.js $LH_TEST_URL $LH_MIN_PASS_SCORE