Skip to content

Commit

Permalink
perf: lazy eval headers from the requestStore (vercel#41353)
Browse files Browse the repository at this point in the history
The `ReadOnlyHeaders` class extends the `Headers` class that is provided
via a polyfill. This incurs some costs the first time it's created
because we need to load that polyfill. This saves approximately 10ms on
my machine on a cold request.

This is only useful when a user does not access headers during the
request of course and when the runtime does not support fetch naitvely.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
2 people authored and Kikobeats committed Oct 24, 2022
1 parent 7461740 commit 6d21856
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions packages/next/server/app-render.tsx
Expand Up @@ -83,6 +83,7 @@ const INTERNAL_COOKIES_INSTANCE = Symbol('internal for cookies readonly')
function readonlyCookiesError() {
return new Error('ReadonlyCookies cannot be modified')
}

class ReadonlyNextCookies {
[INTERNAL_COOKIES_INSTANCE]: NextCookies

Expand Down Expand Up @@ -1602,18 +1603,33 @@ export async function renderToHTMLOrFlight(
(renderOpts as any).previewProps
)

let cachedHeadersInstance: ReadonlyHeaders | undefined
let cachedCookiesInstance: ReadonlyNextCookies | undefined

const requestStore = {
headers: new ReadonlyHeaders(headersWithoutFlight(req.headers)),
cookies: new ReadonlyNextCookies({
headers: {
get: (key) => {
if (key !== 'cookie') {
throw new Error('Only cookie header is supported')
}
return req.headers.cookie
},
},
}),
get headers() {
if (!cachedHeadersInstance) {
cachedHeadersInstance = new ReadonlyHeaders(
headersWithoutFlight(req.headers)
)
}
return cachedHeadersInstance
},
get cookies() {
if (!cachedCookiesInstance) {
cachedCookiesInstance = new ReadonlyNextCookies({
headers: {
get: (key) => {
if (key !== 'cookie') {
throw new Error('Only cookie header is supported')
}
return req.headers.cookie
},
},
})
}
return cachedCookiesInstance
},
previewData,
}

Expand Down

0 comments on commit 6d21856

Please sign in to comment.