How to Use gatsby-remark-images to Compress Images in Gatsby.js Articles
Thank you for your continued support.
This article contains advertisements that help fund our operations.
Table Of Contents
An overview of how to use the Gatsby.js plugin gatsby-remark-images.
What is gatsby-remark-images?
First, in the context of Gatsby.js plugins, plugins with remark in the name are often tools that format and build Markdown articles.
The main feature of gatsby-remark-images is that it processes image files written within Markdown articles. For example, it can optimize the images by reducing their size or adjusting their dimensions during the build process.
Features
Actual Experience with the Plugin
- It builds and makes images responsive.
- Prevents layout shifts caused by images loading during page load (CLS: Cumulative Layout Shift).
- Serves the optimal image size for different devices.
- Displays a blurred version of the image before fully loading, which is almost 0 bytes.
- Optimizes images by converting them to WebP format.
- Supports lazy loading for images.
These are some of the features I appreciated.
Installation
Install the necessary plugins with the command
npm install gatsby-remark-images gatsby-plugin-sharp gatsby-transformer-remarkAdd to gatsby.config.js
Be cautious about plugin duplication and add gatsby-remark-images.
plugins: [
`gatsby-plugin-sharp`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 620,
},
},
],
},
},
]Place images in the location defined by the filesystem or define a new location
gatsby.config.js
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content-images`,
path: `${__dirname}/src/images`,
},
},Call images from the md file using relative paths
The path may vary depending on your environment.
If you're unsure about path specifications, this article provides more details.
How to Compress Images in WebP Format within Gatsby.js Articles
Check the behavior in more detail
Output results
<a
class="gatsby-resp-image-link"
href="/static/70b8b9146729bb8ea24a7cbd117c0fd7/21b4d/mailtrap.png"
target="_blank"
rel="noopener"
style="display: block;"
>
<span
class="gatsby-resp-image-background-image"
style='padding-bottom: 56.3291%; position: relative; bottom: 0px; left: 0px; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB8klEQVR42n1Sz2sTQRjda7E3wZvWopYePFgL1bb2IhZBIfXYv6UH0ZNS9WRQ/xRPohdRkSIiaNBKQ2o3SZPsr9md2czsPt9MUmNscOAx385+35v3fW+882sbOHXxOrYeVGFXHAtobWCMQTeIEfK7KEqicDBmhEnLW1ytYPbCCu5vP3MHqVTQw+Taz33sNXyINEWcWAiITEIqhT4vnUi4vr6J+SsVVB8+BVSGpNFAfnAANH0kQiCMEkdk9yhOoFSOvN93xWVZHoO3unYHly/dQPXJc5dkkgQQBHfFwoi7yHhRKpBZZRyF0hqS/ybBm1/ZwMm5a7g7bNnO7miJNEMvjJCTIKC6mLFWklAONvdfeHPLFZyYXca97aFCFlO7i2WeUyFN4VnYbCL3fSCKUHa7Dkd5YzM8t3Qb02evkvC4QkVCq7JgK2GrhZSG6GKyu38ITy/cxNTM0kjhX4SSBghpHdVIWm0k7TZkHMPIDMbuLpYwVG2icNDymf8QWlMOf/kIG/vI6nVIui97PWSdjovNYZsmkpTqDUcyTvjoxYCQKmBnRGdNECBlYaf2jcbHSHXfXWJNylmsywJ8LOMtzyzewpSd4eMBod7dRVnfQxmyBZJ1ewFqtR94/fIV3rzbwfuPn/H2wyd8+fodJefp3l8xeoe/AeOtFm22gmcCAAAAAElFTkSuQmCC"); background-size: cover; display: block; opacity: 0;'
></span>
<picture>
<source
srcset="/static/70b8b9146729bb8ea24a7cbd117c0fd7/81b7c/mailtrap.webp 158w /static/70b8b9146729bb8ea24a7cbd117c0fd7/6ea66/mailtrap.webp 315w /static/70b8b9146729bb8ea24a7cbd117c0fd7/8aab1/mailtrap.webp 630w /static/70b8b9146729bb8ea24a7cbd117c0fd7/a70f5/mailtrap.webp 945w /static/70b8b9146729bb8ea24a7cbd117c0fd7/4ef06/mailtrap.webp 1260w /static/70b8b9146729bb8ea24a7cbd117c0fd7/af3f0/mailtrap.webp 1280w"
sizes="(max-width: 630px) 100vw, 630px"
type="image/webp"
/>
<source
srcset="/static/70b8b9146729bb8ea24a7cbd117c0fd7/c26ae/mailtrap.png 158w /static/70b8b9146729bb8ea24a7cbd117c0fd7/6bdcf/mailtrap.png 315w /static/70b8b9146729bb8ea24a7cbd117c0fd7/f058b/mailtrap.png 630w /static/70b8b9146729bb8ea24a7cbd117c0fd7/40601/mailtrap.png 945w /static/70b8b9146729bb8ea24a7cbd117c0fd7/78612/mailtrap.png 1260w /static/70b8b9146729bb8ea24a7cbd117c0fd7/21b4d/mailtrap.png 1280w"
sizes="(max-width: 630px) 100vw, 630px"
type="image/png"
/>
<img
class="gatsby-resp-image-image"
src="/static/70b8b9146729bb8ea24a7cbd117c0fd7/f058b/mailtrap.png"
alt="mailtrap"
title=""
loading="lazy"
decoding="async"
style="width: 100%; height: 100%; margin: 0px; vertical-align: middle; position: absolute; top: 0px; left: 0px; opacity: 1; color: inherit; box-shadow: white 0px 0px 0px 400px inset;"
/>
</picture>
</a>Optimal Image Size for Devices
Looking at the output results, files corresponding to 158w, 315w, 630w, 945w, 1260w, and 1280w are defined.
This ensures that devices are not unnecessarily retrieving larger files than needed.
By the way, 630 is the max-width specified, and 1280 seems to be the original image width.
Preventing Layout Shift Due to Image Loading (CLS: Cumulative Layout Shift)
The span tag above the picture tag provides padding-bottom according to the aspect ratio of the image, which fills the space until the actual image is loaded. This mechanism ensures that the layout doesn't shift once the image is loaded.
By the way,
Image width = 630px
Image height = 355px
Aspect ratio
= (height / width) * 100
= (355 / 630) * 100
= 56.3291%
The percentage varies with each image, so the plugin calculates and applies the correct size to the HTML based on the image's dimensions. It's amazing!
Showing a Blurred Image (Almost 0 Bytes) Before the Full Image is Loaded
Similarly, the span tag contains a background-image, which appears to be a base64-encoded blurred image.
This image acts as the background until the actual image is displayed.
Image Compression with WebP Format
By configuring options in gatsby-config.js, the images are compressed and optimized to WebP format, reducing their file size.
The option settings will be covered later, so they are omitted here.
Lazy Loading
The img tag includes
loading="lazy"This enables lazy loading for the images.
Also,
decoding="async"and it fetches the image data asynchronously so that it does not interfere with the fetching of other information on the page.
This is the default setting and can be changed in the options described below.
Optional Settings
You can change the settings by adding them to the options object.
plugins: [
`gatsby-plugin-sharp`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 620,
},
},
],
},
},
]Although reading the documentation should give you a clear idea, I’ll summarize the key points below.
Setting Maximum Width
You can specify the maximum width of the images, and if there is extra space, the image will be centered.
options: {
maxWidth: 620
}Link to Original Image
This feature allows users to click on the image in the article and open the original (uncompressed) image in a new window. It can be toggled between true and false. This is enabled by default.
This feature is useful for images that might be inconvenient to view without zooming.
options: {
linkImagesToOriginal: false
}Display ALT Text Below Image
You can display the ALT text below the image, as shown in the example below.
The text will be taken from the ALT attribute.
options: {
showCaptions: true
}Display Markdown Text Below Image
You can also display the text in markdown format below the image.
As seen in the example above, it will display text formatted in markdown.
If showCaptions is set to false, this won’t be displayed.
options: {
showCaptions: true,
markdownCaptions: true,
},
Add Styles to Wrapper Tag
You can add styles to the span tag that wraps the picture tag.
Various styles can be applied, but in this example, the background color changes when hovering.
options: {
wrapperStyle: "margin-bottom:10px; background: red;",
}Change Background Color
This option applies a background color to the img tag.
This is useful when an image fails to load (e.g., a 404 error). Setting the background color to match the article background will ensure the layout doesn’t look strange.
- Setting it to
transparentwill make the background transparent. - Setting it to
nonewill remove the background completely.
options: {
backgroundColor: "transparent",
}Adjust Resolution for Compression
This option is useful if you need to reduce the resolution for heavy images. However, I recommend trying compression with AVIF or WebP before lowering the resolution.
options: {
quality: 50
}Compress to WebP Format
This option compresses the original image to the WebP format, which offers better compression than JPG. It also supports transparency, making it suitable for images with rounded edges.
It’s difficult to do this manually, so this plugin is very helpful.
options: {
withWebp: true
//withWebp: { quality: 80 },
}Compress to AVIF Format
This option compresses the original image to the AVIF format, which offers even higher compression efficiency than WebP.
This plugin’s ability to do this is highly appreciated.
options: {
withAvif: true,
// withAvif: { quality: 80 },
}Modify Blurry Image During Loading
You can change the blurry placeholder image using the tracedSVG option.
To be honest, I’m not sure how to modify this, but I personally prefer the blurry effect.
Translation: "Instead of the 'blur-up' effect, use a traced SVG as the placeholder image. Set it to
trueto use the default traced SVG, or pass in an options object to customize it (e.g.,{ color: '#F00', turnPolicy: 'TURNPOLICY_MAJORITY' }). For the full list of options and explanations, see the node-potrace parameter documentation."
https://www.gatsbyjs.com/plugins/gatsby-remark-images/#options
(I'm not sure what changes in my test environment.)
tracedSVG: { color: "#F00", turnPolicy: "TURNPOLICY_MAJORITY" }Change Loading Attribute
You can change the loading="lazy" attribute applied to the img tag. This setting controls lazy loading.
options: {
loading: "lazy" // eager, auto
}Load Images Asynchronously
You can change the decoding="async" attribute applied to the img tag, which allows asynchronous loading of images without affecting the loading of other elements.
options: {
decoding: "async" // sync or auto
}Disable Blur-up for Images with Transparent Pixels
Images with transparent pixels may appear unnatural when using the blur-up effect. This option disables the effect for images containing transparent pixels.
Translation: "Images with transparent pixels at the edges will appear blurred. As a result, they don’t work well with the blur-up technique used by this plugin."
options: {
disableBgImageOnAlpha: true,
}Remove Background Images and Styles
This option removes background images and inline styles. It can be useful for preventing AMP’s “Stylesheet too long” error.
AMP is a technique used to display web content faster.
Unless there’s a specific reason, you probably won’t need this setting.
options: {
disableBgImage: true
}Change Breakpoints for Responsive Images
In the previous example, the following breakpoints were set: 158w, 315w, 630w, 945w, 1260w, 1280w.
options: {
srcSetBreakpoints: [200, 340, 520, 890],
}With this setting, the breakpoints were adjusted to 200w, 340w, 520w, 630w, 890w, and 1280w, with 630 and 1280 being the same as before.
What I Liked About the Options
The withWebp and withAvif options are my favorites.
For example, an image of 180 KB was compressed to 300 B, which is about 1/600 of the original size. It doesn’t change much visually, and since users can view the original image by clicking, the UX remains good.
I’m grateful for this.
Drawbacks
The main drawback is the increase in build time. However, even with around 200 articles and 150 images, the total build time is about 5 minutes, which doesn’t seem to have increased significantly.
Additionally, once the images are built, they are likely cached, so the cost won’t increase significantly even with this plugin.
Conclusion
I summarized my experiences and thoughts on the behavior of the gatsby-remark-images plugin. I hope it will be helpful to others.





