From 5dc9346fe38945ca637a538d0d78b41206a31f32 Mon Sep 17 00:00:00 2001 From: Orestis Ioannou Date: Tue, 6 Nov 2018 01:06:41 +0100 Subject: [PATCH] feat(gatsby-plugin-sharp): cache base64 if possible (#9059) Closes: #6999 --- packages/gatsby-plugin-sharp/src/index.js | 49 +++++++++++++------ packages/gatsby-remark-images/src/index.js | 3 +- .../src/extend-node-type.js | 11 +++++ 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 89928e26aaa89..cda7bf9b51548 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -441,7 +441,7 @@ function queueImageResizing({ file, args = {}, reporter }) { } } -async function notMemoizedbase64({ file, args = {}, reporter }) { +async function generateBase64({ file, args, reporter }) { const options = healOptions(args, { width: 20 }) let pipeline try { @@ -484,29 +484,46 @@ async function notMemoizedbase64({ file, args = {}, reporter }) { pipeline ) } - const [buffer, info] = await pipeline.toBufferAsync() - const originalName = file.base - - return { + const base64output = { src: `data:image/${info.format};base64,${buffer.toString(`base64`)}`, width: info.width, height: info.height, aspectRatio: info.width / info.height, - originalName: originalName, + originalName: file.base, } + return base64output } -const memoizedBase64 = _.memoize( - notMemoizedbase64, - ({ file, args }) => `${file.id}${JSON.stringify(args)}` -) +const base64CacheKey = ({ file, args }) => `${file.id}${JSON.stringify(args)}` + +const memoizedBase64 = _.memoize(generateBase64, base64CacheKey) + +const cachifiedBase64 = async ({ cache, ...arg }) => { + const cacheKey = base64CacheKey(arg) + + const cachedBase64 = await cache.get(cacheKey) + if (cachedBase64) { + return cachedBase64 + } + + const base64output = await generateBase64(arg) + + await cache.set(cacheKey, base64output) + + return base64output +} + +async function base64(arg) { + if (arg.cache) { + // Not all tranformer plugins are going to provide cache + return await cachifiedBase64(arg) + } -async function base64(args) { - return await memoizedBase64(args) + return await memoizedBase64(arg) } -async function fluid({ file, args = {}, reporter }) { +async function fluid({ file, args = {}, reporter, cache }) { const options = healOptions(args, {}) // Account for images with a high pixel density. We assume that these types of @@ -634,7 +651,7 @@ async function fluid({ file, args = {}, reporter }) { } // Get base64 version - const base64Image = await base64({ file, args: base64Args, reporter }) + const base64Image = await base64({ file, args: base64Args, reporter, cache }) // Construct src and srcSet strings. const originalImg = _.maxBy(images, image => image.width).src @@ -682,7 +699,7 @@ async function fluid({ file, args = {}, reporter }) { } } -async function fixed({ file, args = {}, reporter }) { +async function fixed({ file, args = {}, reporter, cache }) { const options = healOptions(args, {}) // if no width is passed, we need to resize the image based on the passed height @@ -744,7 +761,7 @@ async function fixed({ file, args = {}, reporter }) { } // Get base64 version - const base64Image = await base64({ file, args: base64Args, reporter }) + const base64Image = await base64({ file, args: base64Args, reporter, cache }) const fallbackSrc = images[0].src const srcSet = images diff --git a/packages/gatsby-remark-images/src/index.js b/packages/gatsby-remark-images/src/index.js index e4360ce60abd5..afb3aed2af772 100644 --- a/packages/gatsby-remark-images/src/index.js +++ b/packages/gatsby-remark-images/src/index.js @@ -15,7 +15,7 @@ const slash = require(`slash`) // 4. Create the responsive images. // 5. Set the html w/ aspect ratio helper. module.exports = ( - { files, markdownNode, markdownAST, pathPrefix, getNode, reporter }, + { files, markdownNode, markdownAST, pathPrefix, getNode, reporter, cache }, pluginOptions ) => { const defaults = { @@ -83,6 +83,7 @@ module.exports = ( file: imageNode, args: options, reporter, + cache, }) if (!fluidResult) { diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index f780630e6f286..c9bc4d7778541 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -51,6 +51,7 @@ const fixedNodeType = ({ getNodeAndSavePathDependency, reporter, name, + cache, }) => { return { type: new GraphQLObjectType({ @@ -80,6 +81,7 @@ const fixedNodeType = ({ file, args, reporter, + cache, }) ).then(({ src }) => src) }, @@ -96,6 +98,7 @@ const fixedNodeType = ({ file, args, reporter, + cache, }) ).then(({ srcSet }) => srcSet) }, @@ -151,6 +154,7 @@ const fixedNodeType = ({ file, args, reporter, + cache, }) ).then(o => Object.assign({}, o, { @@ -169,6 +173,7 @@ const fluidNodeType = ({ getNodeAndSavePathDependency, reporter, name, + cache, }) => { return { type: new GraphQLObjectType({ @@ -194,6 +199,7 @@ const fluidNodeType = ({ file, args, reporter, + cache, }) ).then(({ src }) => src) }, @@ -210,6 +216,7 @@ const fluidNodeType = ({ file, args, reporter, + cache, }) ).then(({ srcSet }) => srcSet) }, @@ -278,6 +285,7 @@ const fluidNodeType = ({ file, args, reporter, + cache, }) ).then(o => Object.assign({}, o, { @@ -295,6 +303,7 @@ module.exports = ({ pathPrefix, getNodeAndSavePathDependency, reporter, + cache, }) => { if (type.name !== `ImageSharp`) { return {} @@ -305,6 +314,7 @@ module.exports = ({ pathPrefix, getNodeAndSavePathDependency, reporter, + cache, } // TODO: Remove resolutionsNode and sizesNode for Gatsby v3 @@ -440,6 +450,7 @@ module.exports = ({ resolve( base64({ file, + cache, }) ) } else {