Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby-plugin-sharp): cache base64 if possible #9059

Merged
merged 11 commits into from
Nov 6, 2018

Conversation

oorestisime
Copy link
Contributor

Closes: #6999

Copy link
Contributor

@DSchau DSchau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments!

packages/gatsby-plugin-sharp/src/index.js Outdated Show resolved Hide resolved
packages/gatsby-plugin-sharp/src/index.js Outdated Show resolved Hide resolved
packages/gatsby-plugin-sharp/src/index.js Outdated Show resolved Hide resolved
packages/gatsby-plugin-sharp/src/index.js Outdated Show resolved Hide resolved
packages/gatsby-remark-images/src/index.js Show resolved Hide resolved
@@ -401,7 +410,7 @@ function queueImageResizing({ file, args = {}, reporter }) {
}
}

async function notMemoizedbase64({ file, args = {}, reporter }) {
async function base64({ file, args = {}, reporter, cache }) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One note on the cache here. We changed (in Gatsby 2.1.5 or so) how plugins get a cache instance. What will happen is that if a plugin, e.g. gatsby-transformer-remark, passes its cache instance to this function, these nodes will be cached at .cache/caches/gatsby-transformer-remark which is probably ok but worth noting!

@pieh any ideas for how we'd improve this? Is it worth improving?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless we allow importing cache manager from gatsby, I don't think there is anything that can be done here so gatsby-plugin-sharp use it's own cache instead of gatsby-transformer-remark or gatsby-transformer-sharp caches

@KyleAMathews
Copy link
Contributor

Thanks for jumping on this!

BTW, did you benchmark the difference in build times with this change?

@oorestisime
Copy link
Contributor Author

oorestisime commented Oct 16, 2018

I didn't run any benchmarks, but running this on a gatsby project with quite a lot of images didn't show any visible performance difference. I am interested in running a proper benchmark actually i am just not sure how i would do it. if anyone has an idea i am open for that!

@KyleAMathews
Copy link
Contributor

Where this PR helps is on the second run as then all the base64 images don't need to recalculated. Without this PR, generating base64s is the same each run and with this, it'd be nearly free the second time. So a test could be add 20 images to a site and query for the base64 of each and test the 1st and 2nd run times with and without this PR.

@oorestisime
Copy link
Contributor Author

oorestisime commented Oct 16, 2018

I ll try and come up with something tonight but i think this wont change much:

in graphiql i run twice this query:

query IndexQuery {
  allFile(
    filter: {extension: { in: ["jpg"]}}
  ) {
    edges {
      node {
        childImageSharp {
          fluid(maxWidth:650, quality: 100) {
            base64
          }
        }
      }
    }
  }

}

and while it takes some time for the first run (144 pictures), it is then almost instant on both cases, even when i add more fields in the params (unless there is cache in the graphiql queries).

@oorestisime
Copy link
Contributor Author

I hope i understood what benchmark you were looking for. AFAIU there is no substantial change.

With Memoize

without cache folder

➜ gatsby develop

(node:32513) ExperimentalWarning: The fs.promises API is experimental
success open and validate gatsby-config — 0.013 s
success load plugins — 0.337 s
success onPreInit — 0.436 s
success delete html and css files from previous builds — 0.386 s
success initialize cache — 0.007 s
success copy gatsby files — 0.008 s
success onPreBootstrap — 0.004 s
success source and transform nodes — 3.727 s
success building schema — 0.382 s
success createPages — 3.960 s
success createPagesStatefully — 0.027 s
success onPreExtractQueries — 0.003 s
success update schema — 0.269 s
success extract queries from components — 0.201 s
success run graphql queries — 0.817 s — 55/55 67.40 queries/second
success write out page data — 0.002 s
success write out redirect data — 0.000 s
success onPostBootstrap — 0.002 s

info bootstrap finished - 12.644 s

(node:32537) ExperimentalWarning: The fs.promises API is experimental
 DONE  Compiled successfully in 6307m

second run

➜ gatsby develop
(node:1117) ExperimentalWarning: The fs.promises API is experimental
success open and validate gatsby-config — 0.010 s
success load plugins — 0.336 s
success onPreInit — 0.383 s
success delete html and css files from previous builds — 0.373 s
success initialize cache — 0.028 s
success copy gatsby files — 0.013 s
success onPreBootstrap — 0.006 s
success source and transform nodes — 1.153 s
success building schema — 0.396 s
success createPages — 0.606 s
success createPagesStatefully — 0.025 s
success onPreExtractQueries — 0.004 s
success update schema — 0.368 s
success extract queries from components — 0.286 s
success run graphql queries — 0.151 s — 43/43 287.89 queries/second
success write out page data — 0.005 s
success write out redirect data — 0.001 s
success onPostBootstrap — 0.002 s

info bootstrap finished - 6.191 s

(node:1128) ExperimentalWarning: The fs.promises API is experimental
 DONE  Compiled successfully in 7129m

building

➜ gatsby build
(node:1250) ExperimentalWarning: The fs.promises API is experimental
success open and validate gatsby-config — 0.013 s
success load plugins — 0.307 s
success onPreInit — 0.455 s
success delete html and css files from previous builds — 0.383 s
success initialize cache — 0.005 s
success copy gatsby files — 0.011 s
success onPreBootstrap — 0.007 s
success source and transform nodes — 0.994 s
success building schema — 0.424 s
success createPages — 0.771 s
success createPagesStatefully — 0.026 s
success onPreExtractQueries — 0.004 s
success update schema — 0.265 s
success extract queries from components — 0.190 s
success run graphql queries — 0.100 s — 43/43 434.18 queries/second
success write out page data — 0.004 s
success write out redirect data — 0.001 s
success onPostBootstrap — 0.002 s

info bootstrap finished - 5.701 s

With cache

without cache folder

➜ gatsby develop
(node:30478) ExperimentalWarning: The fs.promises API is experimental
success open and validate gatsby-config — 0.014 s
success load plugins — 0.395 s
success onPreInit — 0.423 s
success delete html and css files from previous builds — 0.352 s
success initialize cache — 0.020 s
success copy gatsby files — 0.009 s
success onPreBootstrap — 0.004 s
success source and transform nodes — 3.746 s
success building schema — 0.302 s
success createPages — 3.961 s
success createPagesStatefully — 0.024 s
success onPreExtractQueries — 0.003 s
success update schema — 0.307 s
success extract queries from components — 0.219 s
success run graphql queries — 1.054 s — 55/55 52.26 queries/second
success write out page data — 0.002 s
success write out redirect data — 0.000 s
success onPostBootstrap — 0.002 s

info bootstrap finished - 12.669 s

(node:30515) ExperimentalWarning: The fs.promises API is experimental
 DONE  Compiled successfully in 7593ms

second run

➜ gatsby develop
(node:31657) ExperimentalWarning: The fs.promises API is experimental
success open and validate gatsby-config — 0.023 s
success load plugins — 0.396 s
success onPreInit — 0.445 s
success delete html and css files from previous builds — 0.352 s
success initialize cache — 0.021 s
success copy gatsby files — 0.013 s
success onPreBootstrap — 0.004 s
success source and transform nodes — 1.077 s
success building schema — 0.333 s
success createPages — 0.444 s
success createPagesStatefully — 0.026 s
success onPreExtractQueries — 0.005 s
success update schema — 0.258 s
success extract queries from components — 0.198 s
success run graphql queries — 0.143 s — 43/43 304.11 queries/second
success write out page data — 0.003 s
success write out redirect data — 0.000 s
success onPostBootstrap — 0.002 s

info bootstrap finished - 5.657 s

(node:31674) ExperimentalWarning: The fs.promises API is experimental
 DONE  Compiled successfully in 6337ms

building

➜ gatsby build
(node:32042) ExperimentalWarning: The fs.promises API is experimental
success open and validate gatsby-config — 0.012 s
success load plugins — 0.297 s
success onPreInit — 0.441 s
success delete html and css files from previous builds — 0.380 s
success initialize cache — 0.005 s
success copy gatsby files — 0.011 s
success onPreBootstrap — 0.004 s
success source and transform nodes — 0.939 s
success building schema — 0.325 s
success createPages — 0.475 s
success createPagesStatefully — 0.018 s
success onPreExtractQueries — 0.003 s
success update schema — 0.256 s
success extract queries from components — 0.192 s
success run graphql queries — 0.098 s — 43/43 447.57 queries/second
success write out page data — 0.003 s
success write out redirect data — 0.001 s
success onPostBootstrap — 0.002 s

info bootstrap finished - 5.095 s

@pieh pieh changed the title Feature cache plugin sharp feat(gatsby-plugin-sharp): cache base64 if possible Nov 4, 2018
@pieh
Copy link
Contributor

pieh commented Nov 4, 2018

I've been doing more targeted benchmarks with this - this will only affect first rerun of query that has image processing with base64. For test case I've created page with 20 and 200 images and here are results with initial query run (this is using gatsby build):

master with 20 images in query:

gatsby:pr9059 Query for /blur-up/ took 0.999s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.887s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.929s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.988s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.958s +0ms

this pr with 20 images in query:

gatsby:pr9059 Query for /blur-up/ took 0.160s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.153s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.147s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.156s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.151s +0ms

master with 200 images in query:

gatsby:pr9059 Query for /blur-up/ took 8.136s +0ms
gatsby:pr9059 Query for /blur-up/ took 7.924s +0ms
gatsby:pr9059 Query for /blur-up/ took 7.857s +0ms
gatsby:pr9059 Query for /blur-up/ took 8.828s +0ms
gatsby:pr9059 Query for /blur-up/ took 8.284s +0ms

this pr with 200 images in query:

gatsby:pr9059 Query for /blur-up/ took 0.540s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.535s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.560s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.526s +0ms
gatsby:pr9059 Query for /blur-up/ took 0.554s +0ms
- master this PR
20 images 0.9522s 0.1534s
200 images 8.2058s 0.543s

So there definitely is some saving. When using gatsby develop apart of initial query there is no noticeable difference between master and this PR - both are around 0.04s (as cache does hold things in memory as well, so no change on that).

Copy link
Contributor

@pieh pieh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 Thanks @oorestisime!

@pieh pieh merged commit 5dc9346 into gatsbyjs:master Nov 6, 2018
lipis added a commit to lipis/gatsby that referenced this pull request Nov 6, 2018
* 'master' of github.com:gatsbyjs/gatsby: (63 commits)
  Update how-to-contribute.md to mention the style guide when writing blogs/tutorials (gatsbyjs#9742)
  Added  Tylermcginnis website (gatsbyjs#9619)
  Fix grammar and punctuation (gatsbyjs#9498)
  Fix typo of plugin authoring (gatsbyjs#9737)
  Authentication tutorial - small fixes (gatsbyjs#9738)
  chore: move run-sift (gatsbyjs#9549)
  docs: fix minor typo (gatsbyjs#9730)
  chore(release): Publish
  fix(gatsby-plugin-page-creator): ensure that __tests__ directory is actually ignored (gatsbyjs#9720)
  fix: revert admin redirect (gatsbyjs#9728)
  fix: adjust page order to make nested matchPaths work (gatsbyjs#9719)
  feat(gatsby-plugin-sharp): cache base64 if possible (gatsbyjs#9059)
  chore(release): Publish
  fix(gatsby-plugin-offline): Serve the offline shell for short URLs + use no-cors for external resources (gatsbyjs#9679)
  chore(release): Publish
  fix: ensure babel-preset-gatsby can be used with unit tests (gatsbyjs#9629)
  feat(www): Filter posts by date (gatsbyjs#9400)
  fix(blog): azure blog post url date (gatsbyjs#9718)
  feat(blog): Add post on publishing to Azure (gatsbyjs#8868)
  Emphasize importance of promise return on source-plugin docs (gatsbyjs#9650)
  ...
gpetrioli pushed a commit to gpetrioli/gatsby that referenced this pull request Jan 22, 2019
Closes: gatsbyjs#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/
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[gatsby-plugin-sharp] Cache base64 calculations
4 participants