Skip to content

Commit

Permalink
Show warning during build if page is returning a large amount of data (
Browse files Browse the repository at this point in the history
#37264)

## Feature

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

Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
  • Loading branch information
sshyam-gupta and ijjk committed May 29, 2022
1 parent 5739edc commit 3930214
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/next/export/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ export default async function exportApp(
nextScriptWorkers: nextConfig.experimental.nextScriptWorkers,
optimizeFonts: nextConfig.optimizeFonts,
reactRoot: nextConfig.experimental.reactRoot || false,
largePageDataBytes: nextConfig.experimental.largePageDataBytes,
}

const { serverRuntimeConfig, publicRuntimeConfig } = nextConfig
Expand Down
22 changes: 11 additions & 11 deletions packages/next/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -946,20 +946,20 @@ export class NextScript extends Component<OriginProps> {
}

static getInlineScriptSource(context: Readonly<HtmlProps>): string {
const { __NEXT_DATA__ } = context
const { __NEXT_DATA__, largePageDataBytes } = context
try {
const data = JSON.stringify(__NEXT_DATA__)
const bytes = Buffer.from(data).byteLength
const prettyBytes = require('../lib/pretty-bytes').default

if (process.env.NODE_ENV === 'development') {
const bytes = Buffer.from(data).byteLength
const prettyBytes = require('../lib/pretty-bytes').default
if (bytes > 128 * 1000) {
console.warn(
`Warning: data for page "${__NEXT_DATA__.page}" is ${prettyBytes(
bytes
)}, this amount of data can reduce performance.\nSee more info here: https://nextjs.org/docs/messages/large-page-data`
)
}
if (largePageDataBytes && bytes > largePageDataBytes) {
console.warn(
`Warning: data for page "${__NEXT_DATA__.page}" is ${prettyBytes(
bytes
)} which exceeds the threshold of ${prettyBytes(
largePageDataBytes
)}, this amount of data can reduce performance.\nSee more info here: https://nextjs.org/docs/messages/large-page-data`
)
}

return htmlEscapeJsonString(data)
Expand Down
2 changes: 2 additions & 0 deletions packages/next/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
renderServerComponentData?: boolean
serverComponentProps?: any
reactRoot: boolean
largePageDataBytes?: number
}
protected serverOptions: ServerOptions
private incrementalCache: IncrementalCache
Expand Down Expand Up @@ -327,6 +328,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
? this.nextConfig.crossOrigin
: undefined,
reactRoot: this.nextConfig.experimental.reactRoot === true,
largePageDataBytes: this.nextConfig.experimental.largePageDataBytes,
}

// Only the `publicRuntimeConfig` key is exposed to the client side
Expand Down
2 changes: 2 additions & 0 deletions packages/next/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export interface ExperimentalConfig {
swcTraceProfiling?: boolean
forceSwcTransforms?: boolean
swcPlugins?: Array<[string, Record<string, unknown>]>
largePageDataBytes?: number
}

/**
Expand Down Expand Up @@ -516,6 +517,7 @@ export const defaultConfig: NextConfig = {
remotePatterns: [],
},
forceSwcTransforms: false,
largePageDataBytes: 128 * 1000, // 128KB by default
},
}

Expand Down
2 changes: 2 additions & 0 deletions packages/next/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export type RenderOptsPartial = {
crossOrigin?: string
images: ImageConfigComplete
reactRoot: boolean
largePageDataBytes?: number
}

export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial
Expand Down Expand Up @@ -1562,6 +1563,7 @@ export async function renderToHTML(
optimizeFonts: renderOpts.optimizeFonts,
nextScriptWorkers: renderOpts.nextScriptWorkers,
runtime: globalRuntime,
largePageDataBytes: renderOpts.largePageDataBytes,
}

const document = (
Expand Down
1 change: 1 addition & 0 deletions packages/next/shared/lib/html-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export type HtmlProps = {
nextScriptWorkers?: boolean
runtime?: 'edge' | 'nodejs'
hasConcurrentFeatures?: boolean
largePageDataBytes?: number
}

export const HtmlContext = createContext<HtmlProps>(null as any)
Expand Down
16 changes: 8 additions & 8 deletions test/e2e/prerender.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -942,15 +942,15 @@ describe('Prerender', () => {
})
})

if ((global as any).isNextDev) {
it('should show warning when large amount of page data is returned', async () => {
await renderViaHTTP(next.url, '/large-page-data')
await check(
() => next.cliOutput,
/Warning: data for page "\/large-page-data" is 128 kB, this amount of data can reduce performance/
)
})
it('should show warning when large amount of page data is returned', async () => {
await renderViaHTTP(next.url, '/large-page-data')
await check(
() => next.cliOutput,
/Warning: data for page "\/large-page-data" is 256 kB which exceeds the threshold of 128 kB, this amount of data can reduce performance/
)
})

if ((global as any).isNextDev) {
it('should not show warning from url prop being returned', async () => {
const urlPropPage = 'pages/url-prop.js'
await next.patchFile(
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/prerender/pages/large-page-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Link from 'next/link'
export async function getStaticProps({ params }) {
return {
props: {
lotsOfData: new Array(128 * 1000).fill('a').join(''),
lotsOfData: new Array(256 * 1000).fill('a').join(''),
},
revalidate: false,
}
Expand Down

0 comments on commit 3930214

Please sign in to comment.