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

perf(gatsby): test sync before calling onCreateNode #27442

Merged
merged 12 commits into from
Oct 16, 2020
Merged

Conversation

pvdz
Copy link
Contributor

@pvdz pvdz commented Oct 14, 2020

This change allows a plugin to register a shouldOnCreateNode callback which is called when Gatsby is about to schedule a callback for the (async) onCreateNode callback. The scheduling is relatively expensive at scale and the test is often cheap. As a result, this saves roughly 20% of a certain step during bootstrap for some cases (lot's of conditions, but this will apply to most sites to a certain degree). In the site I was benchmarking it drops a minute from a five minute step.

The problem is particular to onCreateNode because it will call the callback for each plugin for every node generated, even though in many cases the plugin may not care about that particular node (sharp does not care about markdown nodes, callback is still scheduled and invoked async).

Turns out that these promises do add quite some back pressure at scale. Who woulda thought.

@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Oct 14, 2020
@pvdz pvdz added topic: performance Related to runtime & build performance topic: scaling builds and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels Oct 14, 2020
@KyleAMathews
Copy link
Contributor

💜 this. Great idea and simple.

Copy link
Contributor

@wardpeet wardpeet left a comment

Choose a reason for hiding this comment

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

I've added some bikeshedding comments, happy to hear what you think.

packages/gatsby/src/utils/api-node-docs.ts Outdated Show resolved Hide resolved
packages/gatsby/src/utils/api-node-docs.ts Outdated Show resolved Hide resolved
packages/gatsby/src/utils/api-runner-node.js Outdated Show resolved Hide resolved
wardpeet
wardpeet previously approved these changes Oct 15, 2020
@pvdz
Copy link
Contributor Author

pvdz commented Oct 15, 2020

Set the version to .79 and also the snapshot that changed because of it. Tests should pass now. Will publish after.

wardpeet
wardpeet previously approved these changes Oct 15, 2020
@pvdz
Copy link
Contributor Author

pvdz commented Oct 15, 2020

Added a pluginOptions arg to the callback because plugins like mdx will need that and it's going to be easier to make that change now than to do it later down the line.

if (
api === `onCreateNode` &&
gatsbyNode?.shouldOnCreateNode && // Don't bail if this api is not exported
!gatsbyNode.shouldOnCreateNode(args.node, plugin.pluginOptions)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a blocker - just to not miss this part:

skipping runAPI makes this not behave like rest of APIs (which is also kind of the point of it), but it changes few things (like right now passing node plainly as first arg as opposed to passing object with node like actual onCreateNode and also not passing rest of "shared" things - https://www.gatsbyjs.com/docs/node-api-helpers/).

I don't think we need all of those helpers in the "test" callback like that (it should be quick check and not rely on anything else other than node itself), but it does introduce first "odd" gatsby-node hook and so we also need to think about user expectations (and our docs)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pieh @wardpeet blocking or not? :)

Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 I agree with @pieh so let's do it differently. Let's call it unstable_shouldOnCreateNode({ node: args.node }, plugin.pluginOptions) so we're unblocked and it shows that it's not a complete API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like that. Will roll with that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

eslint does not approve. Will go with unstableShouldOnCreateNode instead, otherwise every mention of it will also require an eslint suppression line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

plot twist: eslint has been taught a lesson instead

@pvdz pvdz force-pushed the skip-async-oncreatenode branch from 265d524 to 823afb9 Compare October 16, 2020 09:20
wardpeet
wardpeet previously approved these changes Oct 16, 2020
wardpeet
wardpeet previously approved these changes Oct 16, 2020
@pvdz
Copy link
Contributor Author

pvdz commented Oct 16, 2020

I'm going to ignore those starters errors. They seem unrelated and nothing else indicates a failure for this PR.

@pvdz pvdz merged commit 6400383 into master Oct 16, 2020
@delete-merged-branch delete-merged-branch bot deleted the skip-async-oncreatenode branch October 16, 2020 11:21
@pvdz
Copy link
Contributor Author

pvdz commented Oct 16, 2020

Published in [email protected]

pragmaticpat pushed a commit to pragmaticpat/gatsby that referenced this pull request Apr 28, 2022
* perf(gatsby): test sync before calling onCreateNode

* Dont wrap node in object, fix tests

* This snapshot does not fail locally but does on CI

* Must check if value exists too, not just plugin

* Disarm the footgun

* Apply feedback

* Update version and related snapshot

* Add `pluginOptions` as second callback param. Add note about api.

* shouldOnCreateNode -> unstable_shouldOnCreateNode

* it would help if these snapshots were the same locally.

* Also update the first arg to be `{node}` instead of `node`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: performance Related to runtime & build performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants