From 829d92aa4941500aa2d9a3ecccdefb0db67a0b1c Mon Sep 17 00:00:00 2001 From: Janicklas Ralph James Date: Fri, 21 May 2021 16:55:37 -0700 Subject: [PATCH 1/4] Add preconnect. Fix bug --- .../font-stylesheet-gathering-plugin.ts | 2 +- packages/next/next-server/lib/constants.ts | 5 +++-- packages/next/next-server/lib/post-process.ts | 19 ++++++++++++++++++- .../next/next-server/server/font-utils.ts | 9 ++++++++- packages/next/pages/_document.tsx | 7 ++++++- .../fixtures/with-google/pages/_document.js | 12 ++++++------ .../with-typekit/manifest-snapshot.json | 6 +++--- .../font-optimization/test/index.test.js | 13 ++++++++++++- 8 files changed, 57 insertions(+), 16 deletions(-) diff --git a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts index 043c09ca91b29..a3fff7d54fa99 100644 --- a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts +++ b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts @@ -106,7 +106,7 @@ export class FontStylesheetGatheringPlugin { !props.rel || props.rel !== 'stylesheet' || !props.href || - !OPTIMIZED_FONT_PROVIDERS.some((url) => + !OPTIMIZED_FONT_PROVIDERS.some(({ url }) => props.href.startsWith(url) ) ) { diff --git a/packages/next/next-server/lib/constants.ts b/packages/next/next-server/lib/constants.ts index eed0b3877ba92..738b5c354be63 100644 --- a/packages/next/next-server/lib/constants.ts +++ b/packages/next/next-server/lib/constants.ts @@ -37,8 +37,9 @@ export const TEMPORARY_REDIRECT_STATUS = 307 export const PERMANENT_REDIRECT_STATUS = 308 export const STATIC_PROPS_ID = '__N_SSG' export const SERVER_PROPS_ID = '__N_SSP' +export const GOOGLE_FONT_PROVIDER = 'https://fonts.googleapis.com/css' export const OPTIMIZED_FONT_PROVIDERS = [ - 'https://fonts.googleapis.com/css', - 'https://use.typekit.net/', + { url: GOOGLE_FONT_PROVIDER, preconnect: 'https://fonts.gstatic.com' }, + { url: 'https://use.typekit.net/', preconnect: 'https://use.typekit.net' }, ] export const STATIC_STATUS_PAGES = ['/500'] diff --git a/packages/next/next-server/lib/post-process.ts b/packages/next/next-server/lib/post-process.ts index 2a448f64bab56..65ba46d3d9742 100644 --- a/packages/next/next-server/lib/post-process.ts +++ b/packages/next/next-server/lib/post-process.ts @@ -82,7 +82,7 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { (tag: HTMLElement) => tag.getAttribute('rel') === 'stylesheet' && tag.hasAttribute('data-href') && - OPTIMIZED_FONT_PROVIDERS.some((url) => { + OPTIMIZED_FONT_PROVIDERS.some(({ url }) => { const dataHref = tag.getAttribute('data-href') return dataHref ? dataHref.startsWith(url) : false }) @@ -104,6 +104,8 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { options: renderOptions ) => { let result = markup + let preconnectUrls = new Set() + if (!options.getFontDefinition) { return markup } @@ -132,9 +134,24 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { '', `` ) + + const preconnect = OPTIMIZED_FONT_PROVIDERS.find((provider) => + url.startsWith(provider.url) + ).preconnect + preconnectUrls.add(preconnect) } }) + let preconnectTag = '' + preconnectUrls.forEach((url) => { + preconnectTag += `` + }) + + result = result.replace( + '', + preconnectTag + ) + return result } } diff --git a/packages/next/next-server/server/font-utils.ts b/packages/next/next-server/server/font-utils.ts index 4d4b25dbe9425..6e2b9cfee6a3a 100644 --- a/packages/next/next-server/server/font-utils.ts +++ b/packages/next/next-server/server/font-utils.ts @@ -1,4 +1,5 @@ import * as Log from '../../build/output/log' +import { GOOGLE_FONT_PROVIDER } from '../lib/constants' const https = require('https') const CHROME_UA = @@ -10,6 +11,10 @@ export type FontManifest = Array<{ content: string }> +function isGoogleFont(url: string): boolean { + return url.startsWith(GOOGLE_FONT_PROVIDER) +} + function getFontForUA(url: string, UA: string): Promise { return new Promise((resolve, reject) => { let rawData: any = '' @@ -45,7 +50,9 @@ export async function getFontDefinitionFromNetwork( * CSS cascading 🤷‍♂️. */ try { - result += await getFontForUA(url, IE_UA) + if (isGoogleFont(url)) { + result += await getFontForUA(url, IE_UA) + } result += await getFontForUA(url, CHROME_UA) } catch (e) { Log.warn( diff --git a/packages/next/pages/_document.tsx b/packages/next/pages/_document.tsx index d3a486a0e4de9..9faa6ebfd7414 100644 --- a/packages/next/pages/_document.tsx +++ b/packages/next/pages/_document.tsx @@ -447,7 +447,9 @@ export class Head extends Component< if ( c.type === 'link' && c.props['href'] && - OPTIMIZED_FONT_PROVIDERS.some((url) => c.props['href'].startsWith(url)) + OPTIMIZED_FONT_PROVIDERS.some(({ url }) => + c.props['href'].startsWith(url) + ) ) { const newProps = { ...(c.props || {}) } newProps['data-href'] = newProps['href'] @@ -639,6 +641,9 @@ export class Head extends Component< )} {children} + {process.env.__NEXT_OPTIMIZE_FONTS && ( + + )} {head} null + export default class MyDocument extends Document { - constructor(props) { - super(props) - const { __NEXT_DATA__, ids } = props - if (ids) { - __NEXT_DATA__.ids = ids - } + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx) + return { ...initialProps } } render() { @@ -20,6 +19,7 @@ export default class MyDocument extends Document { href="https://fonts.googleapis.com/css?family=Voces" /> {false && } +
diff --git a/test/integration/font-optimization/fixtures/with-typekit/manifest-snapshot.json b/test/integration/font-optimization/fixtures/with-typekit/manifest-snapshot.json index 42681af1533b5..cb517f819778c 100644 --- a/test/integration/font-optimization/fixtures/with-typekit/manifest-snapshot.json +++ b/test/integration/font-optimization/fixtures/with-typekit/manifest-snapshot.json @@ -1,14 +1,14 @@ [ { "url": "https://use.typekit.net/plm1izr.css", - "content": "@import url(\"https://p.typekit.net/p.css?s=1&k=plm1izr&ht=tk&f=32266&a=23152309&app=typekit&e=css\");@font-face{font-family:\"birra-2\";src:url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:700}.tk-birra-2{font-family:\"birra-2\",serif}@import url(\"https://p.typekit.net/p.css?s=1&k=plm1izr&ht=tk&f=32266&a=23152309&app=typekit&e=css\");@font-face{font-family:\"birra-2\";src:url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:700}.tk-birra-2{font-family:\"birra-2\",serif}" + "content": "@import url(\"https://p.typekit.net/p.css?s=1&k=plm1izr&ht=tk&f=32266&a=23152309&app=typekit&e=css\");@font-face{font-family:\"birra-2\";src:url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:700}.tk-birra-2{font-family:\"birra-2\",serif}" }, { "url": "https://use.typekit.net/ucs7mcf.css", - "content": "@import url(\"https://p.typekit.net/p.css?s=1&k=ucs7mcf&ht=tk&f=43886&a=23152309&app=typekit&e=css\");@font-face{font-family:\"flegrei\";src:url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:400}.tk-flegrei{font-family:\"flegrei\",sans-serif}@import url(\"https://p.typekit.net/p.css?s=1&k=ucs7mcf&ht=tk&f=43886&a=23152309&app=typekit&e=css\");@font-face{font-family:\"flegrei\";src:url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:400}.tk-flegrei{font-family:\"flegrei\",sans-serif}" + "content": "@import url(\"https://p.typekit.net/p.css?s=1&k=ucs7mcf&ht=tk&f=43886&a=23152309&app=typekit&e=css\");@font-face{font-family:\"flegrei\";src:url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/74a5d1/00000000000000003b9b3d6e/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:400}.tk-flegrei{font-family:\"flegrei\",sans-serif}" }, { "url": "https://use.typekit.net/erd0sed.css", - "content": "@import url(\"https://p.typekit.net/p.css?s=1&k=erd0sed&ht=tk&f=43885&a=23152309&app=typekit&e=css\");@font-face{font-family:\"pantelleria\";src:url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:400}.tk-pantelleria{font-family:\"pantelleria\",sans-serif}@import url(\"https://p.typekit.net/p.css?s=1&k=erd0sed&ht=tk&f=43885&a=23152309&app=typekit&e=css\");@font-face{font-family:\"pantelleria\";src:url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:400}.tk-pantelleria{font-family:\"pantelleria\",sans-serif}" + "content": "@import url(\"https://p.typekit.net/p.css?s=1&k=erd0sed&ht=tk&f=43885&a=23152309&app=typekit&e=css\");@font-face{font-family:\"pantelleria\";src:url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff2\"),url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"woff\"),url(\"https://use.typekit.net/af/1f141c/00000000000000003b9b3d6f/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3\") format(\"opentype\");font-display:auto;font-style:normal;font-weight:400}.tk-pantelleria{font-family:\"pantelleria\",sans-serif}" } ] diff --git a/test/integration/font-optimization/test/index.test.js b/test/integration/font-optimization/test/index.test.js index da01c47350f83..6ac704e066be8 100644 --- a/test/integration/font-optimization/test/index.test.js +++ b/test/integration/font-optimization/test/index.test.js @@ -54,6 +54,7 @@ describe('Font Optimization', () => { /` ) - const preconnect = OPTIMIZED_FONT_PROVIDERS.find((provider) => - url.startsWith(provider.url) - ).preconnect - preconnectUrls.add(preconnect) + const provider = OPTIMIZED_FONT_PROVIDERS.find((p) => + url.startsWith(p.url) + ) + + if (provider) { + preconnectUrls.add(provider.preconnect) + } } })