From 6ed3866e1b52d4f70609b5fabfb38af220e047b3 Mon Sep 17 00:00:00 2001 From: Shyam Gupta Date: Sat, 28 May 2022 18:08:18 +0530 Subject: [PATCH 1/2] Show warning during build if page is returning a large amount of data --- packages/next/pages/_document.tsx | 18 ++++++++---------- test/e2e/prerender.test.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/next/pages/_document.tsx b/packages/next/pages/_document.tsx index f7f8abaac3852..ee4570f6e1fc1 100644 --- a/packages/next/pages/_document.tsx +++ b/packages/next/pages/_document.tsx @@ -950,16 +950,14 @@ export class NextScript extends Component { try { const data = JSON.stringify(__NEXT_DATA__) - 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` - ) - } + 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` + ) } return htmlEscapeJsonString(data) diff --git a/test/e2e/prerender.test.ts b/test/e2e/prerender.test.ts index 02e39a2566885..d8177167f9a53 100644 --- a/test/e2e/prerender.test.ts +++ b/test/e2e/prerender.test.ts @@ -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 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( From dfd573d52b0167e57a89229f37185ae480b629bf Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Sat, 28 May 2022 20:12:17 -0500 Subject: [PATCH 2/2] Make data size warning configurable --- packages/next/export/index.ts | 1 + packages/next/pages/_document.tsx | 8 +++++--- packages/next/server/base-server.ts | 2 ++ packages/next/server/config-shared.ts | 2 ++ packages/next/server/render.tsx | 2 ++ packages/next/shared/lib/html-context.ts | 1 + test/e2e/prerender.test.ts | 2 +- test/e2e/prerender/pages/large-page-data.js | 2 +- 8 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/next/export/index.ts b/packages/next/export/index.ts index 79a52449b37f3..7166bfeac1385 100644 --- a/packages/next/export/index.ts +++ b/packages/next/export/index.ts @@ -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 diff --git a/packages/next/pages/_document.tsx b/packages/next/pages/_document.tsx index ee4570f6e1fc1..c639698f4b66b 100644 --- a/packages/next/pages/_document.tsx +++ b/packages/next/pages/_document.tsx @@ -946,16 +946,18 @@ export class NextScript extends Component { } static getInlineScriptSource(context: Readonly): 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 (bytes > 128 * 1000) { + + 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` ) } diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index 77fdc077da26d..17dae9483817a 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -177,6 +177,7 @@ export default abstract class Server { renderServerComponentData?: boolean serverComponentProps?: any reactRoot: boolean + largePageDataBytes?: number } protected serverOptions: ServerOptions private incrementalCache: IncrementalCache @@ -327,6 +328,7 @@ export default abstract class Server { ? 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 diff --git a/packages/next/server/config-shared.ts b/packages/next/server/config-shared.ts index 756dd7c5a4570..94393d3eb7a20 100644 --- a/packages/next/server/config-shared.ts +++ b/packages/next/server/config-shared.ts @@ -135,6 +135,7 @@ export interface ExperimentalConfig { swcTraceProfiling?: boolean forceSwcTransforms?: boolean swcPlugins?: Array<[string, Record]> + largePageDataBytes?: number } /** @@ -516,6 +517,7 @@ export const defaultConfig: NextConfig = { remotePatterns: [], }, forceSwcTransforms: false, + largePageDataBytes: 128 * 1000, // 128KB by default }, } diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index ac44868ed2552..8f0431f442ff1 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -243,6 +243,7 @@ export type RenderOptsPartial = { crossOrigin?: string images: ImageConfigComplete reactRoot: boolean + largePageDataBytes?: number } export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial @@ -1562,6 +1563,7 @@ export async function renderToHTML( optimizeFonts: renderOpts.optimizeFonts, nextScriptWorkers: renderOpts.nextScriptWorkers, runtime: globalRuntime, + largePageDataBytes: renderOpts.largePageDataBytes, } const document = ( diff --git a/packages/next/shared/lib/html-context.ts b/packages/next/shared/lib/html-context.ts index b069fca0f49f9..38f881713f2f2 100644 --- a/packages/next/shared/lib/html-context.ts +++ b/packages/next/shared/lib/html-context.ts @@ -39,6 +39,7 @@ export type HtmlProps = { nextScriptWorkers?: boolean runtime?: 'edge' | 'nodejs' hasConcurrentFeatures?: boolean + largePageDataBytes?: number } export const HtmlContext = createContext(null as any) diff --git a/test/e2e/prerender.test.ts b/test/e2e/prerender.test.ts index d8177167f9a53..813fa50b0e4f2 100644 --- a/test/e2e/prerender.test.ts +++ b/test/e2e/prerender.test.ts @@ -946,7 +946,7 @@ describe('Prerender', () => { 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/ + /Warning: data for page "\/large-page-data" is 256 kB which exceeds the threshold of 128 kB, this amount of data can reduce performance/ ) }) diff --git a/test/e2e/prerender/pages/large-page-data.js b/test/e2e/prerender/pages/large-page-data.js index 5293c5669cd50..41cb66471a92d 100644 --- a/test/e2e/prerender/pages/large-page-data.js +++ b/test/e2e/prerender/pages/large-page-data.js @@ -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, }