Skip to content

Commit b789689

Browse files
ascorbicwardpeet
authored andcommitted
feat(gatsby-plugin-sharp): Add support for pngquant speed option (#9563)
This adds a `pngCompressionSpeed` option to image queries, which is passed through to pngquant as the `speed` option. In most cases this shouldn't be used, but in some cases with large numbers of PNGs this can make a significant difference in build times. As explained in [imagemin-pngquant](https://github.com/imagemin/imagemin-pngquant#imageminpngquantoptionsinput); _"Speed 10 has 5% lower quality, but is 8 times faster than the default."_ [Contrary to the docs](kornelski/pngquant#313) in pngquant and imagemin-pngquant, the default seems to be 0, not 3. I initially defaulted to 3, but the snapshots broke, which is how I saw that the docs were wrong.
1 parent ebea397 commit b789689

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

packages/gatsby-plugin-sharp/README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ image formats.
1212
For JPEGs it generates progressive images with a default quality level of 50.
1313

1414
For PNGs it uses [pngquant](https://github.com/pornel/pngquant) to compress
15-
images. By default it uses a quality setting of [50-75].
15+
images. By default it uses a quality setting of [50-75]. The `pngCompressionSpeed`
16+
value is a speed/quality trade-off from 1 (brute-force) to 10 (fastest). Speed
17+
10 has 5% lower quality, but is 8 times faster than the default (4). In most
18+
cases you should stick with the default, but if you have very large numbers
19+
of PNGs then it can significantly reduce build times.
1620

1721
## Install
1822

@@ -118,6 +122,7 @@ following:
118122
- `duotone` (bool|obj, default: false)
119123
- `toFormat` (string, default: '')
120124
- `cropFocus` (string, default: '[sharp.strategy.attention][6]')
125+
- `pngCompressionSpeed` (int, default: 4)
121126

122127
#### toFormat
123128

packages/gatsby-plugin-sharp/src/__tests__/__snapshots__/index.js.snap

+11-11
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ Object {
1515
"aspectRatio": 2.0661764705882355,
1616
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABAklEQVQoz61R7WrCQBDM+7+Cv1qhlIogoUWMoH8KrfgOLVXRKDV4d7kkl6/pbsxpqBIo9mBuZ7N3k51bB7TKsrwZVsexyS2rKerwFhYFVI1DnkMQOHIuCaLB+ayuwXlMaApXgvMoxjTU8MIQE4rMx8SnNffUkU/qM/bbiPAeRfgw5n8tB+QgO1kmUvwROdm0kYHmUNoe+NoU2wZTdVjQH7Isg9YRpFIXor8vpGmKjb/FQQgslit8fi3wvQ/OHXLhxRvDHY7Qd5+x3e2udmNzTUN4fZvhoddH566L+8cn9AZuVcvpLR3e9kEAISWEkDAmbRXkGCcJ1r4PRRNPEkPu9Kn2Azs0CqJYU3JKAAAAAElFTkSuQmCC",
1717
"density": 144,
18-
"originalImg": "/static/1234/e2565/test.png",
18+
"originalImg": "/static/1234/a3030/test.png",
1919
"originalName": undefined,
2020
"presentationHeight": 68,
2121
"presentationWidth": 141,
2222
"sizes": "(max-width: 141px) 100vw, 141px",
23-
"src": "/static/1234/e2565/test.png",
24-
"srcSet": "/static/1234/0b382/test.png 200w,
25-
/static/1234/e2565/test.png 281w",
23+
"src": "/static/1234/a3030/test.png",
24+
"srcSet": "/static/1234/56b42/test.png 200w,
25+
/static/1234/a3030/test.png 281w",
2626
"srcSetType": "image/png",
2727
}
2828
`;
@@ -32,14 +32,14 @@ Object {
3232
"aspectRatio": 2.0661764705882355,
3333
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABAklEQVQoz61R7WrCQBDM+7+Cv1qhlIogoUWMoH8KrfgOLVXRKDV4d7kkl6/pbsxpqBIo9mBuZ7N3k51bB7TKsrwZVsexyS2rKerwFhYFVI1DnkMQOHIuCaLB+ayuwXlMaApXgvMoxjTU8MIQE4rMx8SnNffUkU/qM/bbiPAeRfgw5n8tB+QgO1kmUvwROdm0kYHmUNoe+NoU2wZTdVjQH7Isg9YRpFIXor8vpGmKjb/FQQgslit8fi3wvQ/OHXLhxRvDHY7Qd5+x3e2udmNzTUN4fZvhoddH566L+8cn9AZuVcvpLR3e9kEAISWEkDAmbRXkGCcJ1r4PRRNPEkPu9Kn2Azs0CqJYU3JKAAAAAElFTkSuQmCC",
3434
"density": 144,
35-
"originalImg": "/static/1234/76aa7/test.png",
35+
"originalImg": "/static/1234/67b29/test.png",
3636
"originalName": undefined,
3737
"presentationHeight": 136,
3838
"presentationWidth": 281,
3939
"sizes": "(max-width: 281px) 100vw, 281px",
40-
"src": "/static/1234/76aa7/test.png",
41-
"srcSet": "/static/1234/304a5/test.png 200w,
42-
/static/1234/76aa7/test.png 281w",
40+
"src": "/static/1234/67b29/test.png",
41+
"srcSet": "/static/1234/4df82/test.png 200w,
42+
/static/1234/67b29/test.png 281w",
4343
"srcSetType": "image/png",
4444
}
4545
`;
@@ -49,13 +49,13 @@ Object {
4949
"aspectRatio": 1,
5050
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGElEQVQ4y2P4TwFgGNU8qnlU86jmgdUMAOBEq42KgAyMAAAAAElFTkSuQmCC",
5151
"density": 72,
52-
"originalImg": "/static/1234/7bb67/test.png",
52+
"originalImg": "/static/1234/4ce1a/test.png",
5353
"originalName": undefined,
5454
"presentationHeight": 1,
5555
"presentationWidth": 1,
5656
"sizes": "(max-width: 1px) 100vw, 1px",
57-
"src": "/static/1234/7bb67/test.png",
58-
"srcSet": "/static/1234/7bb67/test.png 1w",
57+
"src": "/static/1234/4ce1a/test.png",
58+
"srcSet": "/static/1234/4ce1a/test.png 1w",
5959
"srcSetType": "image/png",
6060
}
6161
`;

packages/gatsby-plugin-sharp/src/index.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ const generalArgs = {
8585
quality: 50,
8686
jpegProgressive: true,
8787
pngCompressionLevel: 9,
88+
// default is 4 (https://github.com/kornelski/pngquant/blob/4219956d5e080be7905b5581314d913d20896934/rust/bin.rs#L61)
89+
pngCompressionSpeed: 4,
8890
base64: false,
8991
grayscale: false,
9092
duotone: false,
@@ -97,6 +99,7 @@ const healOptions = (args, defaultArgs) => {
9799
let options = _.defaults({}, args, defaultArgs, generalArgs)
98100
options.quality = parseInt(options.quality, 10)
99101
options.pngCompressionLevel = parseInt(options.pngCompressionLevel, 10)
102+
options.pngCompressionSpeed = parseInt(options.pngCompressionSpeed, 10)
100103
options.toFormat = options.toFormat.toLowerCase()
101104

102105
// only set width to 400 if neither width nor height is passed
@@ -230,7 +233,6 @@ const processFile = (file, jobs, cb, reporter) => {
230233
job.outsideResolve()
231234
}
232235
}
233-
234236
if (
235237
(job.file.extension === `png` && args.toFormat === ``) ||
236238
args.toFormat === `png`
@@ -245,7 +247,10 @@ const processFile = (file, jobs, cb, reporter) => {
245247
quality: `${args.quality}-${Math.min(
246248
args.quality + 25,
247249
100
248-
)}`, // e.g. 40-65
250+
)}`,
251+
speed: args.pngCompressionSpeed
252+
? args.pngCompressionSpeed
253+
: undefined,
249254
strip: !!pluginOptions.stripMetadata, // Must be a bool
250255
}),
251256
],
@@ -554,7 +559,6 @@ async function base64(arg) {
554559

555560
async function fluid({ file, args = {}, reporter, cache }) {
556561
const options = healOptions(args, {})
557-
558562
// Account for images with a high pixel density. We assume that these types of
559563
// images are intended to be displayed at their native resolution.
560564
let metadata

packages/gatsby-transformer-sharp/src/extend-node-type.js

+14
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const fsExtra = require(`fs-extra`)
2121
const imageSize = require(`probe-image-size`)
2222
const path = require(`path`)
2323

24+
const DEFAULT_PNG_COMPRESSION_SPEED = 4
25+
2426
const {
2527
ImageFormatType,
2628
ImageCropFocusType,
@@ -117,6 +119,10 @@ const fixedNodeType = ({
117119
type: GraphQLBoolean,
118120
defaultValue: true,
119121
},
122+
pngCompressionSpeed: {
123+
type: GraphQLInt,
124+
defaultValue: DEFAULT_PNG_COMPRESSION_SPEED,
125+
},
120126
grayscale: {
121127
type: GraphQLBoolean,
122128
defaultValue: false,
@@ -243,6 +249,10 @@ const fluidNodeType = ({
243249
type: GraphQLBoolean,
244250
defaultValue: true,
245251
},
252+
pngCompressionSpeed: {
253+
type: GraphQLInt,
254+
defaultValue: DEFAULT_PNG_COMPRESSION_SPEED,
255+
},
246256
duotone: {
247257
type: DuotoneGradientType,
248258
defaultValue: false,
@@ -413,6 +423,10 @@ module.exports = ({
413423
type: GraphQLInt,
414424
defaultValue: 9,
415425
},
426+
pngCompressionSpeed: {
427+
type: GraphQLInt,
428+
defaultValue: DEFAULT_PNG_COMPRESSION_SPEED,
429+
},
416430
grayscale: {
417431
type: GraphQLBoolean,
418432
defaultValue: false,

0 commit comments

Comments
 (0)