Skip to content

Commit a278e94

Browse files
authored
fix: avoid creation of buffers for read ops (#56421)
Example usage of `readFileSync().toString()` first creates a `Buffer` instance and later does another C++ call to convert Buffer to UTF-8. This pull request reduces the C++ calls.
1 parent f8308c9 commit a278e94

File tree

5 files changed

+37
-39
lines changed

5 files changed

+37
-39
lines changed

packages/next/src/export/helpers/create-incremental-cache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ export function createIncrementalCache(
3535
notFoundRoutes: [],
3636
}),
3737
fs: {
38-
readFile: (f) => fs.promises.readFile(f),
39-
readFileSync: (f) => fs.readFileSync(f),
38+
readFile: fs.promises.readFile,
39+
readFileSync: fs.readFileSync,
4040
writeFile: (f, d) => fs.promises.writeFile(f, d),
4141
mkdir: (dir) => fs.promises.mkdir(dir, { recursive: true }),
4242
stat: (f) => fs.promises.stat(f),

packages/next/src/server/lib/incremental-cache/file-system-cache.ts

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export default class FileSystemCache implements CacheHandler {
7575
if (!this.tagsManifestPath || !this.fs || tagsManifest) return
7676
try {
7777
tagsManifest = JSON.parse(
78-
this.fs.readFileSync(this.tagsManifestPath).toString('utf8')
78+
this.fs.readFileSync(this.tagsManifestPath, 'utf8')
7979
)
8080
} catch (err: any) {
8181
tagsManifest = { version: 1, items: {} }
@@ -131,9 +131,7 @@ export default class FileSystemCache implements CacheHandler {
131131
const { mtime } = await this.fs.stat(filePath)
132132

133133
const meta = JSON.parse(
134-
(
135-
await this.fs.readFile(filePath.replace(/\.body$/, '.meta'))
136-
).toString('utf8')
134+
await this.fs.readFile(filePath.replace(/\.body$/, '.meta'), 'utf8')
137135
)
138136

139137
const cacheEntry: CacheHandlerValue = {
@@ -155,7 +153,7 @@ export default class FileSystemCache implements CacheHandler {
155153
pathname: fetchCache ? key : `${key}.html`,
156154
fetchCache,
157155
})
158-
const fileData = (await this.fs.readFile(filePath)).toString('utf-8')
156+
const fileData = await this.fs.readFile(filePath, 'utf8')
159157
const { mtime } = await this.fs.stat(filePath)
160158

161159
if (fetchCache) {
@@ -178,37 +176,36 @@ export default class FileSystemCache implements CacheHandler {
178176
}
179177
} else {
180178
const pageData = isAppPath
181-
? (
179+
? await this.fs.readFile(
180+
(
181+
await this.getFsPath({
182+
pathname: `${key}.rsc`,
183+
appDir: true,
184+
})
185+
).filePath,
186+
'utf8'
187+
)
188+
: JSON.parse(
182189
await this.fs.readFile(
183190
(
184191
await this.getFsPath({
185-
pathname: `${key}.rsc`,
186-
appDir: true,
192+
pathname: `${key}.json`,
193+
appDir: false,
187194
})
188-
).filePath
195+
).filePath,
196+
'utf8'
189197
)
190-
).toString('utf8')
191-
: JSON.parse(
192-
(
193-
await this.fs.readFile(
194-
(
195-
await this.getFsPath({
196-
pathname: `${key}.json`,
197-
appDir: false,
198-
})
199-
).filePath
200-
)
201-
).toString('utf8')
202198
)
203199

204200
let meta: { status?: number; headers?: OutgoingHttpHeaders } = {}
205201

206202
if (isAppPath) {
207203
try {
208204
meta = JSON.parse(
209-
(
210-
await this.fs.readFile(filePath.replace(/\.html$/, '.meta'))
211-
).toString('utf-8')
205+
await this.fs.readFile(
206+
filePath.replace(/\.html$/, '.meta'),
207+
'utf8'
208+
)
212209
)
213210
} catch {}
214211
}

packages/next/src/server/lib/node-fs-methods.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import _fs from 'fs'
22
import type { CacheFs } from '../../shared/lib/utils'
33

44
export const nodeFs: CacheFs = {
5-
readFile: (f) => _fs.promises.readFile(f),
6-
readFileSync: (f) => _fs.readFileSync(f),
5+
readFile: _fs.promises.readFile,
6+
readFileSync: _fs.readFileSync,
77
writeFile: (f, d) => _fs.promises.writeFile(f, d),
88
mkdir: (dir) => _fs.promises.mkdir(dir, { recursive: true }),
99
stat: (f) => _fs.promises.stat(f),

packages/next/src/server/next-server.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -722,14 +722,13 @@ export default class NextNodeServer extends BaseServer {
722722
)
723723
}
724724

725-
protected async getFallback(page: string): Promise<string> {
725+
protected getFallback(page: string): Promise<string> {
726726
page = normalizePagePath(page)
727727
const cacheFs = this.getCacheFilesystem()
728-
const html = await cacheFs.readFile(
729-
join(this.serverDistDir, 'pages', `${page}.html`)
728+
return cacheFs.readFile(
729+
join(this.serverDistDir, 'pages', `${page}.html`),
730+
'utf8'
730731
)
731-
732-
return html.toString('utf8')
733732
}
734733

735734
protected async handleNextImageRequest(
@@ -985,10 +984,11 @@ export default class NextNodeServer extends BaseServer {
985984
return this.runApi(req, res, query, match)
986985
}
987986

988-
protected async getPrefetchRsc(pathname: string) {
989-
return this.getCacheFilesystem()
990-
.readFile(join(this.serverDistDir, 'app', `${pathname}.prefetch.rsc`))
991-
.then((res) => res.toString())
987+
protected getPrefetchRsc(pathname: string): Promise<string> {
988+
return this.getCacheFilesystem().readFile(
989+
join(this.serverDistDir, 'app', `${pathname}.prefetch.rsc`),
990+
'utf8'
991+
)
992992
}
993993

994994
protected getCacheFilesystem(): CacheFs {

packages/next/src/shared/lib/utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { NextRouter } from './router/router'
77
import type { ParsedUrlQuery } from 'querystring'
88
import type { PreviewData } from 'next/types'
99
import { COMPILER_NAMES } from './constants'
10+
import type fs from 'fs'
1011

1112
export type NextComponentType<
1213
Context extends BaseContext = NextPageContext,
@@ -447,8 +448,8 @@ export class MiddlewareNotFoundError extends Error {
447448
}
448449

449450
export interface CacheFs {
450-
readFile(f: string): Promise<Buffer>
451-
readFileSync(f: string): Buffer
451+
readFile: typeof fs.promises.readFile
452+
readFileSync: typeof fs.readFileSync
452453
writeFile(f: string, d: any): Promise<void>
453454
mkdir(dir: string): Promise<void | string>
454455
stat(f: string): Promise<{ mtime: Date }>

0 commit comments

Comments
 (0)