Skip to content

Commit ddcfbd8

Browse files
lovellpieh
andauthored
feat(gatsby-plugin-sharp): reduce encoding time and install size (#32851)
* feat(gatsby-plugin-sharp): reduce encoding time and install size - Upgrade sharp to v0.29.0 - Replace use of imagemin with sharp equivalents - Reduces JPEG, PNG and AVIF encoding time by up to 50% - Reduces install size/time by ~10% (~19MB smaller) * sync sharp version in all packages (#1) Co-authored-by: Michal Piechowiak <[email protected]>
1 parent 1706d8f commit ddcfbd8

File tree

8 files changed

+55
-570
lines changed

8 files changed

+55
-570
lines changed

docs/docs/conceptual/image-plugin-architecture.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The plugin exports a number of other helper functions designed to help end-users
3030

3131
### `gatsby-plugin-sharp`
3232

33-
This includes the actual image processing functions from both sharp but also imagemin and potrace. It includes the functions that generate the image data object, including calculating which srcset sizes to generate. It exports `generateImageData`, which is used by `gatsby-transformer-sharp` and `gatsby-plugin-image`. It takes a `File` node and the image processing arguments, calculates which images to generate, processes these images and returns an image data object suitable for passing to `GatsbyImage`. It also exports helper functions for third party plugins to use, such as `traceSVG`.
33+
This includes the actual image processing functions from sharp and potrace. It includes the functions that generate the image data object, including calculating which srcset sizes to generate. It exports `generateImageData`, which is used by `gatsby-transformer-sharp` and `gatsby-plugin-image`. It takes a `File` node and the image processing arguments, calculates which images to generate, processes these images and returns an image data object suitable for passing to `GatsbyImage`. It also exports helper functions for third party plugins to use, such as `traceSVG`.
3434

3535
### `gatsby-transformer-sharp`
3636

packages/gatsby-plugin-manifest/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"gatsby-core-utils": "^2.13.0-next.0",
1212
"gatsby-plugin-utils": "^1.13.0-next.0",
1313
"semver": "^7.3.5",
14-
"sharp": "^0.28.3"
14+
"sharp": "^0.29.0"
1515
},
1616
"devDependencies": {
1717
"@babel/cli": "^7.14.8",

packages/gatsby-plugin-sharp/package.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
"gatsby-plugin-utils": "^1.13.0-next.0",
1717
"gatsby-telemetry": "^2.13.0-next.0",
1818
"got": "^10.7.0",
19-
"imagemin": "^7.0.1",
20-
"imagemin-mozjpeg": "^9.0.0",
21-
"imagemin-pngquant": "^9.0.2",
2219
"lodash": "^4.17.21",
2320
"mini-svg-data-uri": "^1.3.3",
2421
"potrace": "^2.1.8",
2522
"probe-image-size": "^6.0.0",
2623
"progress": "^2.0.3",
2724
"semver": "^7.3.4",
28-
"sharp": "^0.28.3",
25+
"sharp": "^0.29.0",
2926
"svgo": "1.3.2",
3027
"uuid": "3.4.0"
3128
},

packages/gatsby-plugin-sharp/src/process-file.js

+3-58
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ const fs = require(`fs-extra`)
33
const path = require(`path`)
44
const debug = require(`debug`)(`gatsby:gatsby-plugin-sharp`)
55
const duotone = require(`./duotone`)
6-
const imagemin = require(`imagemin`)
7-
const imageminMozjpeg = require(`imagemin-mozjpeg`)
8-
const imageminPngquant = require(`imagemin-pngquant`)
96
const { healOptions } = require(`./plugin-options`)
107
const { SharpError } = require(`./sharp-error`)
118
const { createContentDigest } = require(`gatsby-core-utils`)
@@ -113,6 +110,7 @@ exports.processFile = (file, transforms, options = {}) => {
113110
.png({
114111
compressionLevel: transformArgs.pngCompressionLevel,
115112
adaptiveFiltering: false,
113+
quality: transformArgs.pngQuality || transformArgs.quality,
116114
force: transformArgs.toFormat === `png`,
117115
})
118116
.webp({
@@ -127,15 +125,12 @@ exports.processFile = (file, transforms, options = {}) => {
127125
quality: transformArgs.quality,
128126
force: transformArgs.toFormat === `avif`,
129127
})
130-
131-
// jpeg
132-
if (!options.useMozJpeg) {
133-
clonedPipeline = clonedPipeline.jpeg({
128+
.jpeg({
129+
mozjpeg: options.useMozJpeg,
134130
quality: transformArgs.jpegQuality || transformArgs.quality,
135131
progressive: transformArgs.jpegProgressive,
136132
force: transformArgs.toFormat === `jpg`,
137133
})
138-
}
139134

140135
// grayscale
141136
if (transformArgs.grayscale) {
@@ -156,22 +151,6 @@ exports.processFile = (file, transforms, options = {}) => {
156151
)
157152
}
158153

159-
// lets decide how we want to save this transform
160-
if (transformArgs.toFormat === `png`) {
161-
await compressPng(clonedPipeline, outputPath, {
162-
pngQuality: transformArgs.pngQuality,
163-
quality: transformArgs.quality,
164-
pngCompressionSpeed: transformArgs.compressionSpeed,
165-
stripMetadata: options.stripMetadata,
166-
})
167-
return transform
168-
}
169-
170-
if (options.useMozJpeg && transformArgs.toFormat === `jpg`) {
171-
await compressJpg(clonedPipeline, outputPath, transformArgs)
172-
return transform
173-
}
174-
175154
try {
176155
await clonedPipeline.toFile(outputPath)
177156
} catch (err) {
@@ -192,40 +171,6 @@ exports.processFile = (file, transforms, options = {}) => {
192171
})
193172
}
194173

195-
const compressPng = (pipeline, outputPath, options) =>
196-
pipeline.toBuffer().then(sharpBuffer =>
197-
imagemin
198-
.buffer(sharpBuffer, {
199-
plugins: [
200-
imageminPngquant({
201-
quality: [
202-
(options.pngQuality || options.quality) / 100,
203-
Math.min(((options.pngQuality || options.quality) + 25) / 100, 1),
204-
], // e.g. [0.4, 0.65]
205-
speed: options.pngCompressionSpeed
206-
? options.pngCompressionSpeed
207-
: undefined,
208-
strip: !!options.stripMetadata, // Must be a bool
209-
}),
210-
],
211-
})
212-
.then(imageminBuffer => fs.writeFile(outputPath, imageminBuffer))
213-
)
214-
215-
const compressJpg = (pipeline, outputPath, options) =>
216-
pipeline.toBuffer().then(sharpBuffer =>
217-
imagemin
218-
.buffer(sharpBuffer, {
219-
plugins: [
220-
imageminMozjpeg({
221-
quality: options.jpegQuality || options.quality,
222-
progressive: options.jpegProgressive,
223-
}),
224-
],
225-
})
226-
.then(imageminBuffer => fs.writeFile(outputPath, imageminBuffer))
227-
)
228-
229174
exports.createArgsDigest = args => {
230175
const argsDigest = createContentDigest(args)
231176

packages/gatsby-remark-images-contentful/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"is-relative-url": "^3.0.0",
2323
"lodash": "^4.17.21",
2424
"semver": "^7.3.2",
25-
"sharp": "^0.28.3",
25+
"sharp": "^0.29.0",
2626
"unist-util-select": "^3.0.4"
2727
},
2828
"devDependencies": {

packages/gatsby-source-shopify/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"gatsby-core-utils": "^2.13.0-next.0",
2323
"gatsby-source-filesystem": "^3.13.0-next.0",
2424
"node-fetch": "^2.6.1",
25-
"sharp": "^0.28.3",
25+
"sharp": "^0.29.0",
2626
"shift-left": "^0.1.5"
2727
},
2828
"devDependencies": {

packages/gatsby-transformer-sharp/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"potrace": "^2.1.8",
1515
"probe-image-size": "^6.0.0",
1616
"semver": "^7.3.5",
17-
"sharp": "^0.28.3"
17+
"sharp": "^0.29.0"
1818
},
1919
"devDependencies": {
2020
"@babel/cli": "^7.14.8",

0 commit comments

Comments
 (0)