Skip to content

Commit

Permalink
feat(gatsby-plugin-sharp): cache base64 if possible (#9059)
Browse files Browse the repository at this point in the history
Closes: #6999  
<!--
  Q. Which branch should I use for my pull request?
  A. Use `master` branch (probably).

  Q. Which branch if my change is a bug fix for Gatsby v1?
  A. In this case, you should use the `v1` branch

  Q. Which branch if I'm still not sure?
  A. Use `master` branch. Ask in the PR if you're not sure and a Gatsby maintainer will be happy to help :)

  Note: We will only accept bug fixes for Gatsby v1. New features should be added to Gatsby v2.

  Learn more about contributing: https://www.gatsbyjs.org/docs/how-to-contribute/
-->
  • Loading branch information
oorestisime authored and pieh committed Nov 6, 2018
1 parent 0496ce9 commit 5dc9346
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
49 changes: 33 additions & 16 deletions packages/gatsby-plugin-sharp/src/index.js
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion packages/gatsby-remark-images/src/index.js
Expand Up @@ -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 = {
Expand Down Expand Up @@ -83,6 +83,7 @@ module.exports = (
file: imageNode,
args: options,
reporter,
cache,
})

if (!fluidResult) {
Expand Down
11 changes: 11 additions & 0 deletions packages/gatsby-transformer-sharp/src/extend-node-type.js
Expand Up @@ -51,6 +51,7 @@ const fixedNodeType = ({
getNodeAndSavePathDependency,
reporter,
name,
cache,
}) => {
return {
type: new GraphQLObjectType({
Expand Down Expand Up @@ -80,6 +81,7 @@ const fixedNodeType = ({
file,
args,
reporter,
cache,
})
).then(({ src }) => src)
},
Expand All @@ -96,6 +98,7 @@ const fixedNodeType = ({
file,
args,
reporter,
cache,
})
).then(({ srcSet }) => srcSet)
},
Expand Down Expand Up @@ -151,6 +154,7 @@ const fixedNodeType = ({
file,
args,
reporter,
cache,
})
).then(o =>
Object.assign({}, o, {
Expand All @@ -169,6 +173,7 @@ const fluidNodeType = ({
getNodeAndSavePathDependency,
reporter,
name,
cache,
}) => {
return {
type: new GraphQLObjectType({
Expand All @@ -194,6 +199,7 @@ const fluidNodeType = ({
file,
args,
reporter,
cache,
})
).then(({ src }) => src)
},
Expand All @@ -210,6 +216,7 @@ const fluidNodeType = ({
file,
args,
reporter,
cache,
})
).then(({ srcSet }) => srcSet)
},
Expand Down Expand Up @@ -278,6 +285,7 @@ const fluidNodeType = ({
file,
args,
reporter,
cache,
})
).then(o =>
Object.assign({}, o, {
Expand All @@ -295,6 +303,7 @@ module.exports = ({
pathPrefix,
getNodeAndSavePathDependency,
reporter,
cache,
}) => {
if (type.name !== `ImageSharp`) {
return {}
Expand All @@ -305,6 +314,7 @@ module.exports = ({
pathPrefix,
getNodeAndSavePathDependency,
reporter,
cache,
}

// TODO: Remove resolutionsNode and sizesNode for Gatsby v3
Expand Down Expand Up @@ -440,6 +450,7 @@ module.exports = ({
resolve(
base64({
file,
cache,
})
)
} else {
Expand Down

0 comments on commit 5dc9346

Please sign in to comment.