Created
December 19, 2020 17:47
-
-
Save bravetheheat/d0eeb93c15d689d769b3194629ce36ab to your computer and use it in GitHub Desktop.
NEXT.js Async to Defer Pagespeed Hack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NextScript } from 'next/document'; | |
function dedupe<T extends { file: string }>(bundles: T[]): T[] { | |
const files = new Set<string>(); | |
const kept: T[] = []; | |
for (const bundle of bundles) { | |
if (files.has(bundle.file)) continue; | |
files.add(bundle.file); | |
kept.push(bundle); | |
} | |
return kept; | |
} | |
type DocumentFiles = { | |
sharedFiles: readonly string[]; | |
pageFiles: readonly string[]; | |
allFiles: readonly string[]; | |
}; | |
/** | |
* Custom NextScript to defer loading of unnecessary JS. | |
* Standard behavior is async. Compatible with Next.js 10.0.3 | |
*/ | |
class DeferNextScript extends NextScript { | |
getDynamicChunks(files: DocumentFiles) { | |
const { | |
dynamicImports, | |
assetPrefix, | |
isDevelopment, | |
devOnlyCacheBusterQueryString, | |
} = this.context; | |
return dedupe(dynamicImports).map((bundle) => { | |
if (!bundle.file.endsWith('.js') || files.allFiles.includes(bundle.file)) | |
return null; | |
return ( | |
<script | |
defer={!isDevelopment} | |
key={bundle.file} | |
src={`${assetPrefix}/_next/${encodeURI( | |
bundle.file | |
)}${devOnlyCacheBusterQueryString}`} | |
nonce={this.props.nonce} | |
crossOrigin={ | |
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN | |
} | |
/> | |
); | |
}); | |
} | |
getScripts(files: DocumentFiles) { | |
const { | |
assetPrefix, | |
buildManifest, | |
isDevelopment, | |
devOnlyCacheBusterQueryString, | |
} = this.context; | |
const normalScripts = files.allFiles.filter((file) => file.endsWith('.js')); | |
const lowPriorityScripts = buildManifest.lowPriorityFiles?.filter((file) => | |
file.endsWith('.js') | |
); | |
return [...normalScripts, ...lowPriorityScripts].map((file) => { | |
return ( | |
<script | |
key={file} | |
src={`${assetPrefix}/_next/${encodeURI( | |
file | |
)}${devOnlyCacheBusterQueryString}`} | |
nonce={this.props.nonce} | |
defer={!isDevelopment} | |
crossOrigin={ | |
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN | |
} | |
/> | |
); | |
}); | |
} | |
} | |
export default DeferNextScript; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how to use this file bro