diff --git a/packages/next/next-server/lib/post-process.ts b/packages/next/next-server/lib/post-process.ts index 76770819f9701..fc446f581189a 100644 --- a/packages/next/next-server/lib/post-process.ts +++ b/packages/next/next-server/lib/post-process.ts @@ -13,24 +13,9 @@ type postProcessOptions = { type renderOptions = { getFontDefinition?: (url: string) => string } - -type PostProcessData = { - preloads: { - images: Array - } -} - interface PostProcessMiddleware { - inspect: ( - originalDom: HTMLElement, - data: PostProcessData, - options: renderOptions - ) => void - mutate: ( - markup: string, - data: PostProcessData, - options: renderOptions - ) => Promise + inspect: (originalDom: HTMLElement, options: renderOptions) => any + mutate: (markup: string, data: any, options: renderOptions) => Promise } type middlewareSignature = { @@ -58,18 +43,13 @@ async function processHTML( if (!middlewareRegistry[0]) { return html } - const postProcessData: PostProcessData = { - preloads: { - images: [], - }, - } const root: HTMLElement = parse(html) let document = html // Calls the middleware, with some instrumentation and logging async function callMiddleWare(middleware: PostProcessMiddleware) { // let timer = Date.now() - middleware.inspect(root, postProcessData, data) - document = await middleware.mutate(document, postProcessData, data) + const inspectData = middleware.inspect(root, data) + document = await middleware.mutate(document, inspectData, data) // timer = Date.now() - timer // if (timer > MIDDLEWARE_TIME_BUDGET) { // TODO: Identify a correct upper limit for the postprocess step @@ -89,15 +69,11 @@ async function processHTML( } class FontOptimizerMiddleware implements PostProcessMiddleware { - fontDefinitions: (string | undefined)[][] = [] - inspect( - originalDom: HTMLElement, - _data: PostProcessData, - options: renderOptions - ) { + inspect(originalDom: HTMLElement, options: renderOptions) { if (!options.getFontDefinition) { return } + const fontDefinitions: (string | undefined)[][] = [] // collecting all the requested font definitions originalDom .querySelectorAll('link') @@ -115,30 +91,35 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { const nonce = element.getAttribute('nonce') if (url) { - this.fontDefinitions.push([url, nonce]) + fontDefinitions.push([url, nonce]) } }) + + return fontDefinitions } mutate = async ( markup: string, - _data: PostProcessData, + fontDefinitions: string[][], options: renderOptions ) => { let result = markup if (!options.getFontDefinition) { return markup } - for (const key in this.fontDefinitions) { - const [url, nonce] = this.fontDefinitions[key] + + fontDefinitions.forEach((fontDef) => { + const [url, nonce] = fontDef const fallBackLinkTag = `` if ( result.indexOf(`` ) } - } + }) + return result } } class ImageOptimizerMiddleware implements PostProcessMiddleware { - inspect(originalDom: HTMLElement, _data: PostProcessData) { + inspect(originalDom: HTMLElement) { + const imgPreloads = [] const imgElements = originalDom.querySelectorAll('img') let eligibleImages: Array = [] for (let i = 0; i < imgElements.length; i++) { @@ -169,18 +152,18 @@ class ImageOptimizerMiddleware implements PostProcessMiddleware { } } - _data.preloads.images = [] - for (const imgEl of eligibleImages) { const src = imgEl.getAttribute('src') if (src) { - _data.preloads.images.push(src) + imgPreloads.push(src) } } + + return imgPreloads } - mutate = async (markup: string, _data: PostProcessData) => { + mutate = async (markup: string, imgPreloads: string[]) => { let result = markup - let imagePreloadTags = _data.preloads.images + let imagePreloadTags = imgPreloads .filter((imgHref) => !preloadTagAlreadyExists(markup, imgHref)) .reduce( (acc, imgHref) => diff --git a/test/integration/font-optimization/pages/with-font.js b/test/integration/font-optimization/pages/with-font.js new file mode 100644 index 0000000000000..b9f8875b371fc --- /dev/null +++ b/test/integration/font-optimization/pages/with-font.js @@ -0,0 +1,30 @@ +import Head from 'next/head' +import Link from 'next/link' + +const WithFont = () => { + return ( + <> + + + + +
+ Page with custom fonts +
+
+ Without font +
+ + ) +} + +export const getServerSideProps = async () => { + return { + props: {}, + } +} + +export default WithFont diff --git a/test/integration/font-optimization/pages/without-font.js b/test/integration/font-optimization/pages/without-font.js new file mode 100644 index 0000000000000..2185cb252e07e --- /dev/null +++ b/test/integration/font-optimization/pages/without-font.js @@ -0,0 +1,26 @@ +import Head from 'next/head' +import Link from 'next/link' + +const WithoutFont = () => { + return ( + <> + + + +
+ Page without custom fonts +
+
+ With font +
+ + ) +} + +export const getServerSideProps = async () => { + return { + props: {}, + } +} + +export default WithoutFont diff --git a/test/integration/font-optimization/test/index.test.js b/test/integration/font-optimization/test/index.test.js index 5c2323af2a1ba..317a3477d39a8 100644 --- a/test/integration/font-optimization/test/index.test.js +++ b/test/integration/font-optimization/test/index.test.js @@ -102,6 +102,25 @@ function runTests() { ) }) + it('should only inline included fonts per page', async () => { + const html = await renderViaHTTP(appPort, '/with-font') + expect(await fsExists(builtPage('font-manifest.json'))).toBe(true) + expect(html).toContain( + '' + ) + expect(html).toMatch( + /