Lighthouse guide

Elements on this page:

Lighthouse guide

Welcome to the dick measuring contest among Frontend Developers.

The Lighthouse test is a tool to ensure all aspects of a site is as good as possible according to a set of rules.
Browser support and overall user experience is not reflected in the Lighthouse test, yet.

It is advised from Lighthouse to combine the test with manual testing for optimal results.

- Yes, you can acheive perfect score on a useless site, but the challenge is to achieve it on a usable one.

The test can be performed here:

The test can be made directly from the browser under developer tools, but the performance score will most likely not be correct, as it depends on location, if no CDN is used.

Frequently heard quotes about lighthouse, that are wrong.

Google does not have a perfect score, so it is useless.
- Loud Developer

Google does not need to, it sets a certain perceived standard. Performing equal, or even better than Google would be a good thing, always.

Secondly, why would Google need SEO?

If we don't have 100% it will affect our SEO.
- Client, Manager or SEO nutjob.

Obviously, there is some correlation between the SEO performance and SEO. Though the other parameters are overshadowed completely, by good content.

Look at alexa ratings, most of them are not even close to 100%, it is by no means necessary.

Just make an empty page and get a perfect score.
- Bad Developer

An empty site will result in this:

Showing a picture of a Lighthouse test that fails. As you cannot simply make an empty page and get a perfect score.

Good, now that is out of the way lets start.


Do you work for a SEO Agency of sorts?


The 2 golden rules

  1. Content > Marketing
  2. Copy Paste or write from Meta Tags below.

Every image, that is relevant for the context, should have an alt text describing the image, and every <a> tag should have description.

For images that are not relevant for the context, use the CSS property background-image, as it does not require alt text, lighthouse does.

- Yes, you can cut corners and just write alt="img" and it will work.

Font should 12px or bigger

Meta tags

At the top of the document, before <head> inset the following:

<!DOCTYPE html>
<html lang="en">

Replace "en" with the language of the webpage.
Obviously end the tag again at the bottom of the page </html>.

<title>Lighthouse guide</title>
<meta charset="UTF-8">
<meta name="description" content="It does not matter what you type here, really, just keep typing until its say 100%">
<meta name="viewport" content="width=device-width, initial-scale=0.5 user-scalable=1">
<meta name="robots" content="index,follow">

Replace Title, Content and initial-scale with whatever matches your website.


Best Practise

The 3 golden rules

  1. Only link and or use HTTPS.
  2. Code defensive and don't use libraries you can't vouch for.
  3. Know what size images you will use and size them appropriately.


Unless you really know what you are doing, then this is all you will ever need:

@import url('');
font-family: Arial, Helvetica, sans-serif;
font-family: 'Montserrat', sans-serif;

Apply a basic font such as Arial, Helvetica or Times New Roman as a base font, this enables the page to render without waiting for the desired font.


Load the minimum you need and load the rest eventually.

The built-in functions dispatchEvent and queueMicrotask are amazing to avoid blocking time.

Try this in console:

window.addEventListener('timeToLoadMoreScripts', function(){
console.log("Okay so browser is idle, time for the heavy scripts.");

console.log("I will just chill until whenever.")
let eventToBeEmitted = new Event("timeToLoadMoreScripts",{
bubbles: true

console.log("When all the important stuff is done I will run.")

console.log("I am important and therefore first.")

Minimize console errors with defensive programming.

By asking if the element exists before manipulating the element, you won't have undefined erros.
Both ternary ? : or simply conditional statements works, both cases shown below.

let elm = document.getElementById("placeElementsHere");
elm ? elm.classList.add("newClass") : console.log("elm does not exist");

Images and next gen formats

Issue: Serves images with low resolution

This usually boils down to pixel density or image stretching.
Make sure your image with and height are no bigger than the image including the width=device-width and initial-scale.
The width and scale can be tested with Lighthouse mobile test..

Issue: Properly size images

This is not applicable on background images and can therefore be used as such to avoid this.
If it must be an <img> tag then state the desired initial width and height on the element and not just in the CSS.

Issue: Serve images in next-gen formats

Webp, AVIF and JPEG XL are contrary to the common known formats such as PNG, JPEG and GIF, providing better lossless compression, transparency and animation.
However, it is not necessary to use next-gen formats at all, it simply means use better compression. Run your images through compression after scaling them to your needs, and this issue will be solved.


The one single rule.

  1. Make your site accessible for a mom, a grandfather, a blind man and a developer


Both <button> and regular <div> can be used as buttons. Give them the attribute role="button" and relevant label.

Any buttons present on mobile devices should be at least 48px48px. (oddly this is under SEO issues in lighthouse)


Make sure the order is <h1> → <h2> → <h3> etc., only ever have one <h1>.

If you have dynamic content in no particular structured order, then avoid multiple <h> tags and style <p> tags appropriately instead.


Use labels, Aria labels and placeholders, if no other obvious text is present, if you want everybody to be able to use input fields or buttons.

Make all the fancy buttons your like, but include text of some sorts, otherwise not everybody will understand what is going on.

Don't force scroll, lock user scaling or make pop ups with no way of opting out.

Accessibility does not mean cross browser support.


Performance will most likely not be improved in this step alone, but in combination with the previous steps.

First Contentful Paint

The moment you receive feedback that the page is in fact loading and your internet connection is working.


Better hosting and less initial requirements, again load only what you really need first and postpone the rest.

For worldwide use, consider CDN.

Time To interactive

This is vaguely defined, a rule of thumb in my opinion would be after main thread scripting but before queueMicrotask.


Improve by defer loading and reducing the amount of elements in the DOM on initial load.

Speed Index

This is basically an overall rating in seconds.

Total Blocking Time


3rd party content or externally hosted will always cause blocking time. If able defer load them with relevant emitters.

Largest Contentful Paint

Typically this is once the page is loaded in its full state, with all core elements loaded.


Improve by reducing the amount of DOM elements initial load. Keep it under 1500 Elements

Reduce or client side rendering on initial load.

Cumulative Layout Shift

Have you ever clicked on something by accident because the page moved unexpectedly or some popup happened? That is the effect Cumulative Layout Shift.


Reduce it by allocating space, if you have a price label for a product, then make sure it has enough room for both 20$ and 100.000$ without clashing with other elements.

Easy improvements that works

  • Minify all HTML, CSS and Javascript files.
  • Compress all images.
  • Don't use images bigger than the intended size.

Enjoy the fireworks!

A picture of a Lighthouse test with 100%, the test is of this page with the fireworks you got 100% score.

Random Elements

Once you got all that working, you can make whatever you like afterwards.