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

[WIP] Explore persisting queries #95

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

[WIP] Explore persisting queries #95

wants to merge 3 commits into from

Conversation

captbaritone
Copy link
Owner

@captbaritone captbaritone commented Jan 3, 2024

In browser environments or edge computing environments, it would be desirable to make GraphQL execution more light-weight:

  1. Only load resolver code for the fields that your current bundle can actually execute
  2. Perform SDL or query text parsing at runtime
  3. Don't download code for SDL or query text parsing
  4. Don't interpret the query during execution, instead have pre-built code that evaluates the query as a single function

This PR is the start of an exploration in that direction. By piggy-backing on existing persisted query semantics, we can expose a command that will generate a TypeScript module from query text. For now it simply imports the full query, and inlines a pre-parsed query AST (instead of query text).

Currently it does not provide much (if any) value, since I believe that graphql-js is not written in such a way that the unused pieces of code (parser, validator, etc) are removed from the bundle if not used. However, this PR will help us start to explore those idea.

Bundle Size

I've found I can measure the bundle size using esbuild:

➜  yoga git:(persist) ✗ npx esbuild persisted/MyQuery.ts --bundle --outfile=out.js --tree-shaking=true

  out.js  165.5kb

⚡ Done in 12ms

Interestingly switching to more scoped imports makes the bundle size worse! Either way, it looks like some amount of tree-shaking is working.

  • 165.5kb: Baseline
  • 7.2kb: No graphql imports at all, only product code (lower limit)
  • 161.9kb: No schema graphql imports (still large!)
  • 76.2kb No import of execute (significant savings here)
  • 119.5kb (48.8kb minified): Hacking assertSchema out of execute (not possible without hack)
  • 311.5kb Replace pre-parsed query AST with direct call to graphql (which parses and then executes). This shows us how much size we are saving by parsing at persist time.

Note: Sizes are not minified, but our goal here is to understand where the "meat" of the weight it, so that's okay for this phase. To test minified size, pass esbuild --minify.

Copy link

netlify bot commented Jan 3, 2024

Deploy Preview for grats failed.

Name Link
🔨 Latest commit b9fad47
🔍 Latest deploy log https://app.netlify.com/sites/grats/deploys/65c16a9df251e70009f7f567

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.

None yet

1 participant