Gatsby - Image Optimization 🌃

Suprabha - Aug 9 '20 - - Dev Community

In Gatsby, image optimization can be done with installing couple gatsby plugins. 😎

$ npm i gatsby-transformer-sharp gatsby-plugin-sharp gatsby-background-image
Enter fullscreen mode Exit fullscreen mode

sharp is third party library that does image transformation.

The difference between plugin and transformer, the plugin is going to install Sharp and make Sharp available to do various things. The Transformer looks for nodes that are images and will apply image transformation to them.

gatsby-config.js:

plugins: 
  ['gatsby-transformer-sharp',
      'gatsby-plugin-sharp',
        {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'images',
        path: 'images'
      }
    }
  ]
Enter fullscreen mode Exit fullscreen mode

After adding above configs, Gatsby will understand that images need to be optimised which is in images folder and can be transformed by using above plugins.

When you query below snippet:

query {
  allFile(filter:{sourceInstanceName: {eq: "images"}}){
    nodes{
      relativePath
      childImageSharp {
        original{
          width
          height
          src
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

In above query, you will filter sourceInstanceName from allFile which is equal to "images"

Then, will get the list of images in the path.

Output:

{
  "data": {
    "allFile": {
      "nodes": [
        {
          "relativePath": "banner.jpg",
          "childImageSharp": {
            "original": {
              "width": 3727,
              "height": 2383,
              "src": "/static/banner-82e4fc0a6d4d32e6aa80db5e026cc3e3.jpg"
            }
          }
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The above snippet will show the original file size or path, but you need to optimise the image. To do that you need to use fluid image under childImageSharp

query {
  allFile(filter:{sourceInstanceName: {eq: "images"}}){
    nodes{
      relativePath
      childImageSharp {
        fluid{
          src
          srcSet
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

After above query, you will get list of optimised images:

{
  "data": {
    "allFile": {
      "nodes": [
        {
          "relativePath": "banner.jpg",
          "childImageSharp": {
            "fluid": {
              "src": "/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/14b42/banner.jpg",
              "srcSet": "/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/f836f/banner.jpg 200w,
                        \\n/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/2244e/banner.jpg 400w,
                        \\n/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/14b42/banner.jpg 800w,
                        \\n/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/47498/banner.jpg 1200w,
                        \\n/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/0e329/banner.jpg 1600w,
                        \\n/static/82e4fc0a6d4d32e6aa80db5e026cc3e3/91e14/banner.jpg 3727w"
            }
          }
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Gatsby taken all images and its created a while array of different size for different viewports and different resolutions.

How you create alias in graphql❓🤔

image: childImageSharp {}


// output
"image": {}
Enter fullscreen mode Exit fullscreen mode

Its almost same as Javascript spread operator. 😯

GraphQl Fragment

How to use it in component 🤔

import React from 'react'
import './hero.scss'
import {Link, graphql, useStaticQuery} from 'gatsby'
import BackgroundImage from 'gatsby-background-image'

const Hero = () => {
  const {image} = useStaticQuery(graphql`
    query {
      image: file(relativePath: {eq: "banner.jpg"}){
        sharp: childImageSharp {
          fluid {
            ...GatsbyImageSharpFluid_withWebp
          }
        }
      }
    }
  `)

  return (
    <BackgroundImage className="hero-bg" fluid={image.sharp.fluid} fadeIn="soft">
      <div className='text-box'>
        <h1>Learning Gatsby</h1>
        <p>Hello, <Link to='/about/'>Learn about me &rarr;</Link></p>
      </div>
      </BackgroundImage>
  )
}

export default Hero
Enter fullscreen mode Exit fullscreen mode

In helpers, Gatsby provides a few helpers GatsbyImageSharpFluid_withWebp which will take care of all resolution and if webp doesn't work on browser then it will take care of what image need to shown at the place.

fadeIn is going to cause really nice blur in image. Once you reload, it will first show blur image and then original image shown.

I have added the image optimisation code here ☺️

🌟 Twitter 👩🏻‍💻 Suprabha.me 🌟 Instagram
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .