Gatbsy ships with a nice utility called gatsby-image
(You can check out the API here). When using the <Img />
component in conjunction with gatbsy-image-sharp
and gatbsy-transform-sharp
you get a modern and graceful way to handle image loading and responsive image sizing.
The default loading prop on a Gatsby Image component is "lazy", however, and this can cause some flickering when navigating from page to page IF your image is above the fold.
Background on Gatsby Image
gatsby-image
works by drawing on GraphQL fragments to generate a React component for handling your images. When the component loads it will load with a srcSet
of different image qualities, sizes and types. Following a simple example, we query for a local project image using prepared GraphQL fragments:
file(relativePath: { eq: "images/default.jpg" }) {
childImageSharp {
fluid(maxWidth: 400) {
...GatsbyImageSharpFluid
}
}
}
This returns an object with the following interface:
export interface FluidObject {
aspectRatio: number
src: string
srcSet: string
sizes: string
base64?: string
tracedSVG?: string
srcWebp?: string
srcSetWebp?: string
media?: string
}
The API is fairly robust and all the options can be found from the link above. You can use the data returned in a gatsby-image
component:
<Img
fluid={data.file.childImageSharp.fluid}
alt="Gatsby Docs are awesome"
/>
The result is actually a <picture>
element with a srcSet
that will load lazily and only load the appropriate image (the image that is best suited for a user's browser).
<div class="gatsby-image-wrapper" style="position: relative; overflow: hidden;">
<div aria-hidden="true" style="width: 100%; padding-bottom: 16%;"></div>
<picture>
<source type="image/webp" srcset="srcSet" sizes="sizes">
<source srcset="srcSet" sizes="sizes">
<img sizes="(max-width: 400px) 100vw, 400px" srcset="srcSet" src="src" alt="Gatsby Image" loading="lazy" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center center; opacity: 1; transition: none 0s ease 0s;">
</picture>
</div>
Gatbsy Image handles JPEGs, PNGs, WebP and Base64 and will output all of them if you tell it to. I really love this pattern.
Fixing the Flicker
Recently I developed a Gatsby/Wordpress starter repo and used Gatsby Image for the logo in the header. Clicking from page to page the content loads incredibly fast, but the logo image in the header would flicker every time I changed pages. The fix is incredibly simple. When using the <Img />
component above the fold override the default loading behavior.
This:
<Img
fluid={data.file.childImageSharp.fluid}
alt="Gatsby Docs are awesome"
/>
Becomes this:
<Img
fluid={data.file.childImageSharp.fluid}
alt="Gatsby Docs are awesome"
loading="eager"
/>
I love simple solutions to slightly annoying UI bugs ๐. Check out my starter repo if you are thinking of starting a Gatsby/WP project soon: https://github.com/arnonate/gatbsy-wordpress-starter.
Top comments (1)
Thank you โค๏ธ Itโs too easy to be true ๐ saved my day!