How I got perfect  Google Lighthouse score with Gatsby
Tags: showdev, webdev, webperf, gatsby
Published: 2020-09-28 21:09:59

A few weeks ago, I got assigned a project to open a website for SEO. Targeted keyword is `casino know-hows` and `online casino website`, which are very competitive in local.

I have used [WordPress](https://wordpress.org) and [Wix](https://wix.com) for my SEO projects before. But this time, I decided to use [Gatsby](https://gatsbyjs.com) because:
- It should be blazingly fast for more competitive power
- The website will be purely static
- I wanted to have source code under my control
- I wanted to challenge a new technique
- And of course, it's React, so why not?

It took me 8 days for me to build a website from scratch and deploy to a server. The website [카지노](https://casinohouse.link) has 46 pages. 

[![카지노 | 바카라 | 먹튀 검증 - 카지노 하우스](https://casinohouse.link/img/og-image.jpg)](https://casinohouse.link)

Google lighthouse and gtmetrix score is fairly high.

![카지노 사이트 추천 먹튀 검증 카지노 하우스 casinohouse.link google lighthouse score](https://dev-to-uploads.s3.amazonaws.com/i/c90qejwmxzmap1sux7qi.png)

![바카라 사이트 온라인 카지노 사이트 모음 카지노 하우스 casinohouse.link gtmetrix score](https://dev-to-uploads.s3.amazonaws.com/i/f1kz14ynwg973e5n0qv4.jpg)

<small>* Lighthouse score may vary according to locations and browsers</small>

I'd like to share my experience passing google lighthouse audits:

## Serve images in next-gen formats

You may have seen this message almost every time optimizing your website performance.

Google lighthouse really likes webp but webp images are notorious for not working with iOS browsers. There are workarounds like using `<picture>` tag, but it's a repetitive and dull work. I'm sure many developers give up with webps and just stick to jpg images.

With [gatsby-image](https://gatsbyjs.com/plugins/gatsby-image), you won't have this headache ever again.

For example, I use graphQL queries like this one:

```graphQL
query BlogPostByID($id: String!) {
  markdownRemark(id: { eq: $id }) {
    html
    fields {
      slug
    }
    description
    tag
    featuredimage {
      publicURL
      childImageSharp {
        fluid(maxWidth: 2048, quality: 64) {
          ...GatsbyImageSharpFluid_withWebp
        }
      }
    }
  }
}
```

Then in my component, I render like this:

```javascript
import Img from 'gatsby-image'

<Img fluid={image.childImageSharp.fluid} />
```

Then in my html, I get element like this one:

![바카라 사이트 모음 카지노 사이트 추천 안전놀이터 카지노 하우스 casinohouse.link webp](https://dev-to-uploads.s3.amazonaws.com/i/3q3op9j35jl0lje2gsiv.jpg)

Notice that there is an `img` tag with base64 encoded source. It is the blurred version of the original image. It's first shown before high-quality image is fully loaded. `gatsby-image-sharp` will crop and resize your images and generate thumbnails when you build your pages. All images are sized correctly and much network payload is saved.

It was like magic!

**Gotcha**

Please notice that I set webp quality as 64. [It is known](https://help.shortpixel.com/article/102-why-the-resulting-webp-images-are-bigger-than-the-original-png-files) that lossless (or with 100% quality) webp compression will increase the size by 30%.

In other words, if you set quality to 100, webp image size will be bigger than your original image size.

## Serve static assets with an efficient cache policy

Lighthouse requires you to return `Cache-Control` HTTP response header like this one:

```
Cache-Control: max-age=31536000
```

You can find how to set `Cache-Control` header in nginx and apache in [this artice](https://www.tezify.com/how-to/serve-static-assets-with-an-efficient-cache-policy/).

**Gotcha**

31536000 actually means 365 days or a year. I tried to reduce this value to 10 days(or 864000) but the warning message did not disappear. So I think you should leave it as it is.


## Enable text compression

Gzip compression greatly reduces network bytes by compressing text-based resources.

[Here](https://varvy.com/pagespeed/enable-compression.html#:~:text=The%20ideal%20way%20to%20enable,Gzip%20options%20that%20are%20nearby.) you can find how to enable gzip compression in apache and nginx.

## Background and foreground colors have a sufficient contrast ratio

I've seen many websites fail this audit. You might have to change your color palette if you want to pass this one. 

According to lighthouse:

- Text that is 18pt, or 14pt and bold, needs a contrast ratio of 3:1,
- All other text needs a contrast ratio of 4.5:1

You can put Chrome DevTools's color picker to good use to check your contrast ratio:

![color picker](https://webdev.imgix.net/color-contrast/color-picker.png)

**Gotcha**
If the background uses an image or animated css, lighthouse may not decide contrast ratio. In this case, the audit will be failed although it has enough contrast to the human eyes.

For example, [casinohouse.link](https://casinohouse.link) footer uses css animation. I couldn't persuade lighthouse that the footer had enough contrast ratio. As a workaround, I added another background color to links. And it looked better in that way.

![2020 한국 1위 카지노 커뮤니티 먹튀검증업체 메이저업체 카지노 하우스](https://dev-to-uploads.s3.amazonaws.com/i/rkbnoci8ke8wpqe6sm70.jpg)

## Use HTTP/2 for all of its resources

My hosting web server uses CentOS and apache. Unfortunately, it uses HTTP1.1. I found out that [it was not that easy to make it use http2](https://stackoverflow.com/questions/40720703/how-to-enable-http2-on-centos7). As a workaround, I enabled [cloudflare](https://support.cloudflare.com/hc/en-us/articles/201720164-Creating-a-Cloudflare-account-and-adding-a-website) for my domain. Then, the problem solved within a minute. And it was even FREE!

## Conclusion

All the other audits were already handled by Gatsby. It was really convinient. Although this was the first time I used a Static Site Generator, I got satisfying result and I think my selection was perfect. 

Please take a look around of my [website](https://casinohouse.link) and feel free to suggest any ideas and further optimizations.

Thanks for reading!