Skip to content

Commit

Permalink
Font optimization add preconnect (#25346)
Browse files Browse the repository at this point in the history
  • Loading branch information
janicklas-ralph authored Jun 2, 2021
1 parent 1cb4aaa commit 58a4482
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
)
) {
Expand Down
5 changes: 3 additions & 2 deletions packages/next/next-server/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
22 changes: 21 additions & 1 deletion packages/next/next-server/lib/post-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand All @@ -104,6 +104,8 @@ class FontOptimizerMiddleware implements PostProcessMiddleware {
options: renderOptions
) => {
let result = markup
let preconnectUrls = new Set<string>()

if (!options.getFontDefinition) {
return markup
}
Expand Down Expand Up @@ -132,9 +134,27 @@ class FontOptimizerMiddleware implements PostProcessMiddleware {
'</head>',
`<style data-href="${url}"${nonceStr}>${fontContent}</style></head>`
)

const provider = OPTIMIZED_FONT_PROVIDERS.find((p) =>
url.startsWith(p.url)
)

if (provider) {
preconnectUrls.add(provider.preconnect)
}
}
})

let preconnectTag = ''
preconnectUrls.forEach((url) => {
preconnectTag += `<link rel="preconnect" href="${url}" crossorigin />`
})

result = result.replace(
'<meta name="next-font-preconnect"/>',
preconnectTag
)

return result
}
}
Expand Down
9 changes: 8 additions & 1 deletion packages/next/next-server/server/font-utils.ts
Original file line number Diff line number Diff line change
@@ -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 =
Expand All @@ -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<String> {
return new Promise((resolve, reject) => {
let rawData: any = ''
Expand Down Expand Up @@ -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(
Expand Down
7 changes: 6 additions & 1 deletion packages/next/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down Expand Up @@ -639,6 +641,9 @@ export class Head extends Component<
</>
)}
{children}
{process.env.__NEXT_OPTIMIZE_FONTS && (
<meta name="next-font-preconnect" />
)}
{head}
<meta
name="next-head-count"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react'
/// @ts-ignore
import Document, { Main, NextScript, Head } from 'next/document'

export default class MyDocument extends Document {
constructor(props) {
super(props)
Expand Down
Original file line number Diff line number Diff line change
@@ -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}"
}
]
13 changes: 12 additions & 1 deletion test/integration/font-optimization/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe('Font Optimization', () => {
/<style data-href="https:\/\/fonts\.googleapis\.com\/css2\?family=Roboto:wght@700">.*<\/style>/,
/<style data-href="https:\/\/fonts.googleapis.com\/css2\?family=Roboto:wght@400;700;900&display=swap">.*<\/style>/,
],
'https://fonts.gstatic.com',
],
[
'typekit',
Expand All @@ -69,13 +70,15 @@ describe('Font Optimization', () => {
/<style data-href="https:\/\/use.typekit.net\/ucs7mcf.css">.*<\/style>/,
/<style data-href="https:\/\/use.typekit.net\/ucs7mcf.css">.*<\/style>/,
],
'https://use.typekit.net',
],
])(
'with-%s',
(
property,
[staticFont, staticHeadFont, starsFont, withFont],
[staticPattern, staticHeadPattern, starsPattern, withFontPattern]
[staticPattern, staticHeadPattern, starsPattern, withFontPattern],
preconnectUrl
) => {
const appDir = join(fixturesDir, `with-${property}`)
const nextConfig = join(appDir, 'next.config.js')
Expand Down Expand Up @@ -152,6 +155,14 @@ describe('Font Optimization', () => {
expect(html).toMatch(starsPattern)
})

it(`should add preconnect tag`, async () => {
const html = await renderViaHTTP(appPort, '/stars')
const $ = cheerio.load(html)
expect(
$(`link[rel=preconnect][href="${preconnectUrl}"]`).length
).toBe(1)
})

it('should skip this optimization for AMP pages', async () => {
const html = await renderViaHTTP(appPort, '/amp')
const $ = cheerio.load(html)
Expand Down

0 comments on commit 58a4482

Please sign in to comment.