Skip to content

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.

1 participant