How to optimize images in Gatsby Image
Large and unoptimized images can dramatically slow down our site. Luckily, Gatsby has several useful plugins to optimize images on page components.
Using images in Gatsby requires the following plugins:
- gatsby-source-filesystem plugin allows us to query files with GraphQL
- gatsby-image plugin that automatically creates React components for optimized
- gatsby-transformer-sharp
- gatsby-plugin-sharp
I. Why should we use gatsby-image?
gatsby-image can:
- resize large images to the size needed
- generate multiple sizes of an image so the browser can select the most suitable one for a specific screen size
- lazy load images to speed initial page load and save bandwidth
- hold an image’s position, so the page doesn’t jump around as images load
- use the “blur-up” technique or a ”traced placeholder” SVG to show a preview of the image while it loads
II. Install
1. Install plugins
Before installing the gatsby-image plugin, ensure you have installed a source plugin , so your images are available in graphQl queries.
To install the gatsby-image plugin:
npm install gatsby-image
Depending on our starter theme, we may need to include gatsby-transformer-sharp and gatsby-plugin-sharp plugins.
gatsby-transformer-sharp and gatsby-plugin-sharp help to transform and process our images.
npm install gatsby-transformer-sharp gatsby-plugin-sharp
2. Edit gatsby-config.js
We then add the newly installed plugins to gatsby-config.js.
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: path.join(__dirname, `src`, `images`),
},
},
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
],
};
III. How to use gatsby-image
We can use the gatsby-image in the following steps:
- We import Img component from “gatsby-image.”
- We pass
<Img />component where we want to render the image - The image component can have
fluidprops (if the image is responsive) orfixedprops (if the image has a fixed size). - In the props, add the data as a result from GraphQl image query
Example We have a fixed field
import React from "react"
import { graphql } from "gatsby"
import Img from "gatsby-image"
export default ({ data }) => (
<div>
<h1>Hello gatsby-image</h1>
<Img fixed={data.file.childImageSharp.fixed} />
</div>
)
export const query = graphql`
query {
file(relativePath: { eq: "image-1.jpeg" }) {
childImageSharp {
fixed(width: 125, height: 125) {
...GatsbyImageSharpFixed
}
}
}
}
`
IV. Fragments
Gatsby provides query fragments that are reusable fields.
gatsby-image currently include the fragments for gatsby-transformer-sharp, gatsby-source-contentful, gatsby-source-datocms and gatsby-source-sanity.
gatsby-transformer-sharp
- GatsbyImageSharpFixed
- GatsbyImageSharpFixed_noBase64
- GatsbyImageSharpFixed_tracedSVG
- GatsbyImageSharpFixed_withWebp
- GatsbyImageSharpFixed_withWebp_noBase64
- GatsbyImageSharpFixed_withWebp_tracedSVG
- GatsbyImageSharpFluid
- GatsbyImageSharpFluid_noBase64
- GatsbyImageSharpFluid_tracedSVG
- GatsbyImageSharpFluid_withWebp
- GatsbyImageSharpFluid_withWebp_noBase64
- GatsbyImageSharpFluid_withWebp_tracedSVG
- GatsbyImageSharpFluidLimitPresentationSize
gatsby-source-contentful
- GatsbyContentfulFixed
- GatsbyContentfulFixed_noBase64
- GatsbyContentfulFixed_tracedSVG
- GatsbyContentfulFixed_withWebp
- GatsbyContentfulFixed_withWebp_noBase64
- GatsbyContentfulFluid
- GatsbyContentfulFluid_noBase64
- GatsbyContentfulFluid_tracedSVG
- GatsbyContentfulFluid_withWebp
- GatsbyContentfulFluid_withWebp_noBase64
Example: If we have a fixed image, we have the following options:
- GatsbyImageSharpFixed
- GatsbyImageSharpFixed_noBase64
- GatsbyImageSharpFixed_tracedSVG
- GatsbyImageSharpFixed_withWebp
- GatsbyImageSharpFixed_withWebp_noBase64
- GatsbyImageSharpFixed_withWebp_tracedSVG
We can display our image depending on the fragment.
V. gatsby-image query
Here is an example of fixed and fluid image query.
{
fixed: file(relativePath: {eq: "image-1.jpg"}) {
childImageSharp {
fixed(width: 400, grayscale: true) {
...GatsbyImageSharpFixed
}
}
}
fluid: file(relativePath: {eq: "image-2.jpg"}) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
VI. Image example
import React from 'react'
import { useStaticQuery, graphql } from "gatsby"
import img from "../images/image-1.jpg"
import Img from "gatsby-image"
const getImages = graphql`
{
fixed: file(relativePath: {eq: "image-1.jpg"}) {
childImageSharp {
fixed(width: 400, grayscale: true) {
...GatsbyImageSharpFixed
}
}
}
fluid: file(relativePath: {eq: "image-2.jpg"}) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
`
const Images = () => {
const data = useStaticQuery(getImages)
return (
<section className="images">
<article className="single-image">
<h3>Basic image</h3>
<img src={img} width="30%" alt="beach" />
</article>
<article className="single-image">
<h3>Fixed image / Blur</h3>
<Img fixed={data.fixed.childImageSharp.fixed} />
</article>
<article className="single-image">
<h3>Fluid image</h3>
<Img fluid={data.fluid.childImageSharp.fluid} />
</article>
</section>
)
}
export default Images
The parent container will control the width of the fluid image.
VII. maxWidth
maxWidth is one of the parameters of the fluid field, and it controls the size of images that will be generated using gatsby-image
For example, if we indicate the maxWidth to be 200px but our container is 800px, we will have a blurry image because it has to stretch to fix the container.
{
fluid: file(relativePath: {eq: "image-2.jpg"}) {
childImageSharp {
fluid (maxWidth: 200) {
...GatsbyImageSharpFluid
}
}
}
}