Skip to content

Commit

Permalink
Performance Improvements around 150% (#1073)
Browse files Browse the repository at this point in the history
* Faster?

* ...

* Faster

* Fix imports

* Bump

* Better changesets

* Trigger CI
  • Loading branch information
ardatan authored Apr 13, 2022
1 parent fdd8e15 commit 1d4fe42
Show file tree
Hide file tree
Showing 24 changed files with 357 additions and 260 deletions.
6 changes: 0 additions & 6 deletions .changeset/afraid-fireants-itch.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/long-ducks-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-yoga/common': patch
---

Avoid extra usages of URL constructor which has some performance implications on Node
19 changes: 19 additions & 0 deletions .changeset/moody-birds-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@graphql-yoga/common': minor
---

new option `fetchAPI` has been added;

User can provide a custom Fetch implementation to Yoga like below;

```ts
import { fetch, Request, Response, ReadableStream } from 'my-ponyfill'
createServer({
fetchAPI: {
fetch,
Request,
Response,
ReadableStream,
},
})
```
15 changes: 15 additions & 0 deletions .changeset/odd-fans-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@graphql-yoga/node': patch
---

Use node-fetch by default instead of undici. As discussed in https://github.com/nodejs/undici/issues/1203, `undici`'s fetch implementation has some performance issues compared to `node-fetch` v2.

So Yoga now uses `node-fetch` by default which doesn't affect the existing users. User can configure `cross-undici-fetch` to revert back this behavior;

```ts
import { create } from 'cross-undici-fetch'

createServer({
fetchAPI: create({ useNodeFetch: false }),
})
```
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"**/.git": true,
"**/.DS_Store": true,
"**/node_modules": true,
"**/dist": false,
"**/dist": true,
"test-lib": true,
"lib": true,
"coverage": true,
Expand Down
2 changes: 1 addition & 1 deletion examples/error-handling/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"dependencies": {
"@graphql-yoga/node": "2.1.0",
"cross-undici-fetch": "^0.1.25",
"cross-undici-fetch": "^0.2.4",
"graphql": "^16.1.0",
"ts-node": "10.4.0",
"typescript": "^4.4.4"
Expand Down
4 changes: 1 addition & 3 deletions examples/fastify-modules/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'reflect-metadata'
import { createServer } from '@graphql-yoga/node'
import { Readable } from 'stream'
import fastify, {
FastifyReply,
FastifyRequest,
Expand Down Expand Up @@ -36,8 +35,7 @@ export const graphqlHandler = (): RouteHandlerMethod => {

reply.status(response.status)

const nodeStream = Readable.from(response.body)
reply.send(nodeStream)
reply.send(response.body)
}
}

Expand Down
4 changes: 1 addition & 3 deletions examples/fastify/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { createServer } from '@graphql-yoga/node'
import { Readable } from 'stream'
import fastify, { FastifyReply, FastifyRequest } from 'fastify'

export function buildApp(logging = true) {
Expand Down Expand Up @@ -61,8 +60,7 @@ export function buildApp(logging = true) {
}

reply.status(response.status)
const nodeStream = Readable.from(response.body!)
reply.send(nodeStream)
reply.send(response.body)
},
})

Expand Down
5 changes: 1 addition & 4 deletions examples/koa/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createServer } from '@graphql-yoga/node'
import Koa from 'koa'
import { Readable } from 'stream'

export function buildApp() {
const app = new Koa()
Expand Down Expand Up @@ -47,9 +46,7 @@ export function buildApp() {
ctx.append(key, value)
})

// Converts ReadableStream to a NodeJS Stream
const nodeStream = Readable.from(response.body)
ctx.body = nodeStream
ctx.body = response.body
})

return app
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"resolutions": {
"@changesets/apply-release-plan": "6.0.0",
"graphql": "16.3.0",
"cross-undici-fetch": "0.2.1",
"cross-undici-fetch": "0.2.4",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"@graphql-tools/schema": "^8.3.1",
"@graphql-tools/utils": "^8.6.0",
"@graphql-yoga/subscription": "2.0.0",
"cross-undici-fetch": "^0.2.0",
"cross-undici-fetch": "^0.2.4",
"chalk": "4.1.2",
"dset": "^3.1.1",
"tslib": "^2.3.1"
Expand Down
10 changes: 7 additions & 3 deletions packages/common/src/encodeString.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
let encodeString: (str: string) => Uint8Array
if ('Buffer' in globalThis) {
encodeString = (str) => Buffer.from(str, 'utf-8')
if (globalThis.Buffer) {
encodeString = function encodeStringWithBuffer(str: string) {
return Buffer.from(str, 'utf8')
}
} else {
const textEncoder = new TextEncoder()
encodeString = (str) => textEncoder.encode(str)
encodeString = function encodeStringWithTextEncoder(str: string) {
return textEncoder.encode(str)
}
}

export { encodeString }
11 changes: 6 additions & 5 deletions packages/common/src/getGraphQLParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ type RequestParser = {
export const GETRequestParser: RequestParser = {
is: (request) => request.method === 'GET',
parse: async (request) => {
const url = new URL(request.url)
const operationName = url.searchParams.get('operationName') || undefined
const query = url.searchParams.get('query') || undefined
const variables = url.searchParams.get('variables') || undefined
const extensions = url.searchParams.get('extensions') || undefined
const [, searchParamsStr] = request.url.split('?')
const searchParams = new URLSearchParams(searchParamsStr)
const operationName = searchParams.get('operationName') || undefined
const query = searchParams.get('query') || undefined
const variables = searchParams.get('variables') || undefined
const extensions = searchParams.get('extensions') || undefined
return {
operationName,
query,
Expand Down
153 changes: 0 additions & 153 deletions packages/common/src/getResponse.ts

This file was deleted.

Loading

0 comments on commit 1d4fe42

Please sign in to comment.