Making Images Fast on Gatsby Sites: Why gatsby-plugin-image + Sharp Is Worth the Build Time
Boost page speed and SEO by using Gatsby's gatsby-plugin-image with Sharp for build‑time responsive image optimization.
05 Mar 2026, 06:02 UTC

The Problem: Images Slow Down Your Gatsby Build and Your Users
When you run gatsby build, every image that appears in your markdown, MDX, or JSX is read, copied, and often resized. If you have dozens of high‑resolution photos, the build can take minutes, and the browser may still download large files, hurting Largest Contentful Paint (LCP).
Why the delay matters
Search engines and users care about load speed. A slow LCP can lower rankings and increase bounce rates. The root cause is usually not the image itself, but the fact that the browser receives a single large file instead of a set of appropriately sized variants.
Thesis: Use gatsby-plugin-image with Sharp for Build‑Time Responsive Optimization
gatsby-plugin-image pairs with the Sharp library to generate several resized, format‑converted versions of each image during the Gatsby build. The GatsbyImage component then automatically selects the right size via srcSet and sizes attributes, serving a low‑quality blurred placeholder while the full‑resolution image loads only when needed.
This approach gives you fast page loads without writing custom JavaScript or CSS for responsive images.
How It Works
When you add gatsby-plugin-image to your site, the plugin hooks into the GraphQL data layer. For each image node (typically sourced from gatsby-source-filesystem or gatsby-transformer-sharp), Sharp creates:
- Multiple dimensions (e.g., 200 px, 400 px, 800 px, original)
- Different formats (WebP, AVIF, JPEG) based on your configuration
- A blurred low‑resolution base64 placeholder
The GatsbyImage component reads the generated gatsbyImageData fragment, builds the srcSet list, and injects the sizes attribute so the browser can pick the optimal file for the viewport width.
Worked Example
# 1. Install the required packages (run in your project root)
npm install gatsby-plugin-image @gatsbyjs/sharp
# 2. Add the plugin to gatsby-config.js
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-image',
options: {
// Optional: default quality for WebP/AVIF
defaultImageQuality: 80,
// Optional: enable lazy loading for off‑screen images
loadingBehavior: 'lazy'
}
},
// other plugins …
],
};
# 3. Source an image (example using the filesystem plugin)
# gatsby-config.js also needs gatsby-source-filesystem
{
resolve: 'gatsby-source-filesystem',
name: 'images',
path: './static/images',
},
# 4. Query the image in a component or page
import React from 'react';
import { graphql } from 'gatsby';
import { GatsbyImage } from 'gatsby-plugin-image';
const ImageExample = () => (
Responsive Image Demo
);
export default ImageExample;
// GraphQL query (run in Gatsby GraphQL IDE)
# In your page or component
const data = await graphql(
{
query = `{
image: file(
relativePath: { eq: "sample.jpg" }
) {
gatsbyImageData {
width
height
srcSet
sizes
}
}
}`
}
);
// Verify in the browser dev tools:
// - The element should have a attribute with multiple URLs.
// - The should contain a data-src attribute pointing to the low‑quality placeholder.
// - The rendered size (inspect computed style) should match the viewport width.
Verification steps (run after gatsby develop):
- Start the dev server:
gatsby develop. - Open the page in a browser and inspect the
tag. - Confirm that
srcSetcontains at least three URLs (e.g., 200w, 400w, 800w) and that the sizes attribute reflects the layout. - Open the GraphQL IDE, run the query shown above, and ensure the
gatsbyImageDatafragment resolves without errors. - Check the
.cachedirectory for generated thumbnails; they indicate Sharp processed the source file.
Trade‑off: Longer Build Times
Because all image variants are produced during gatsby build, the more images you have and the higher their original resolution, the longer the build will take. On a CI runner with limited CPU or memory, a site with 500 × 800 px photos can see build times increase by several minutes. This is a real cost to consider, especially for large e‑commerce catalogs.
Mitigation strategies:
- Resize source images before they enter the build (e.g., using a script or a CDN that stores pre‑processed assets).
- Limit the number of format conversions; you can disable WebP or AVIF if they are not needed for your audience.
- Use the
imageSizesoption to specify only the dimensions you actually use in your layouts.
Limitation: Not for Dynamically Uploaded Images
gatsby-plugin-image works best when the image file exists at build time. If you need to optimize user‑uploaded photos, profile pictures, or assets fetched from an external URL, you must either:
- Integrate a runtime image service (e.g., Cloudinary, Imgix) and replace
GatsbyImagewith its component, or - Write a custom node that runs Sharp in a serverless function and stores the optimized files in the file system before the build.
Attempting to feed a remote URL directly to GatsbyImage will not trigger Sharp processing; the plugin only works on local filesystem paths.
Actionable Closing: Adopt, Verify, Monitor
To get the benefits without surprise:
- Add the plugin to
gatsby-config.jsas shown in the example. - Source images locally via
gatsby-source-filesystemorgatsby-transformer-sharp. - Run a quick build comparison: time
gatsby buildwith the plugin disabled, then enable it and note the difference. - Inspect the output using the dev tools and GraphQL query steps above.
- Monitor CI times after each deployment; if build duration grows beyond your tolerance, revisit image sizes or source preprocessing.
By following these steps you’ll turn a potential performance bottleneck into a built‑in advantage, delivering faster pages and better SEO with minimal code changes.