From 2c320c473834f39675b8f4e5ec00fa51fcaca545 Mon Sep 17 00:00:00 2001 From: Janicklas Ralph James Date: Fri, 16 Apr 2021 14:26:31 -0700 Subject: [PATCH] Font optimization bugfix #23896 --- packages/next/next-server/lib/post-process.ts | 70 +++++++------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/packages/next/next-server/lib/post-process.ts b/packages/next/next-server/lib/post-process.ts index c991a5572cd27..08a88dc83f91d 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,14 @@ 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 +70,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 +92,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 +153,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) =>