Skip to content

Instantly share code, notes, and snippets.

@eoguvo
Created February 4, 2021 00:46
Show Gist options
  • Save eoguvo/758e240c43a4ff7c95b5c9ed020343a3 to your computer and use it in GitHub Desktop.
Save eoguvo/758e240c43a4ff7c95b5c9ed020343a3 to your computer and use it in GitHub Desktop.
DeferNextScript to improve performance in FCP and LCP
import { NextScript } from 'next/document';
function dedupe(bundles) {
const files = new Set();
const kept = [];
for (const bundle of bundles) {
if (files.has(bundle.file)) continue;
files.add(bundle.file);
kept.push(bundle);
}
return kept;
}
/**
* 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) {
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) {
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