Skip to content

Commit

Permalink
Merge f724aac into 47a6f27
Browse files Browse the repository at this point in the history
  • Loading branch information
papandreou committed Jul 17, 2020
2 parents 47a6f27 + f724aac commit 2782774
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 173 deletions.
127 changes: 90 additions & 37 deletions lib/subsetFonts.js
Expand Up @@ -20,6 +20,7 @@ const cssListHelpers = require('css-list-helpers');
const LinesAndColumns = require('lines-and-columns').default;
const fontkit = require('fontkit');
const fontFamily = require('font-family-papandreou');
const crypto = require('crypto');

const unquote = require('./unquote');
const normalizeFontPropertyValue = require('./normalizeFontPropertyValue');
Expand Down Expand Up @@ -199,22 +200,6 @@ function getParents(assetGraph, asset, assetQuery) {
return parents;
}

function insertPreconnect(
htmlAsset,
hostname,
insertPoint = htmlAsset.outgoingRelations[0]
) {
return htmlAsset.addRelation(
{
type: 'HtmlPreconnectLink',
hrefType: 'absolute',
to: { url: `https://${hostname}` },
},
'after',
insertPoint
);
}

function asyncLoadStyleRelationWithFallback(htmlAsset, originalRelation) {
// Async load google font stylesheet
// Insert async CSS loading <script>
Expand Down Expand Up @@ -552,6 +537,69 @@ function getFontUsageStylesheet(fontUsages) {
.join('\n\n');
}

const extensionByFormat = {
truetype: '.ttf',
woff: '.woff',
woff2: '.woff2',
};

function md5HexPrefix(stringOrBuffer) {
return crypto
.createHash('md5')
.update(stringOrBuffer)
.digest('hex')
.slice(0, 10);
}

async function createSelfHostedGoogleFontsCssAsset(
assetGraph,
googleFontsCssAsset,
formats
) {
const lines = [];
for (const cssFontFaceSrc of assetGraph.findRelations({
from: googleFontsCssAsset,
type: 'CssFontFaceSrc',
})) {
lines.push(`@font-face {`);
const fontFaceDeclaration = cssFontFaceSrc.node;
fontFaceDeclaration.walkDecls((declaration) => {
const propName = declaration.prop.toLowerCase();
if (propName !== 'src') {
lines.push(` ${propName}: ${declaration.value};`);
}
});
const srcFragments = [];
for (const format of formats) {
const rawSrc = await convertFontBuffer(cssFontFaceSrc.to.rawSrc, format);
const fontAsset = await assetGraph.addAsset({
url: `/subfont/${cssFontFaceSrc.to.baseName}-${md5HexPrefix(rawSrc)}${
extensionByFormat[format]
}`,
rawSrc,
});
srcFragments.push(
`url(${assetGraph.buildRootRelativeUrl(
fontAsset.url
)}) format('${format}')`
);
}
lines.push(` src: ${srcFragments.join(', ')};`, '}');
lines.push(
` unicode-range: ${unicodeRange(
fontkit.create(cssFontFaceSrc.to.rawSrc).characterSet
)};`
);
}
const text = lines.join('\n');
const fallbackAsset = assetGraph.addAsset({
type: 'Css',
url: `/subfont/fallback-${md5HexPrefix(text)}.css`,
text,
});
return fallbackAsset;
}

const validFontDisplayValues = [
'auto',
'block',
Expand Down Expand Up @@ -1339,6 +1387,7 @@ These glyphs are used on your site, but they don't exist in the font you applied
type: 'Css',
url: { $regex: googleFontsCssUrlRegex },
});
const selfHostedGoogleCssByUrl = new Map();
for (const googleFontStylesheet of googleFontStylesheets) {
const seenPages = new Set(); // Only do the work once for each font on each page
for (const googleFontStylesheetRelation of googleFontStylesheet.incomingRelations) {
Expand All @@ -1362,33 +1411,37 @@ These glyphs are used on your site, but they don't exist in the font you applied
}
seenPages.add(htmlParent);

let insertPoint = htmlParent.outgoingRelations.find(
(relation) => relation.type === 'HtmlStyle'
);

if (omitFallbacks) {
googleFontStylesheetRelation.detach();
} else {
// Resource hint: preconnect to the Google font stylesheet hostname
insertPoint = insertPreconnect(
htmlParent,
googleFontStylesheetRelation.to.hostname,
insertPoint
if (!omitFallbacks) {
let selfHostedGoogleFontsCssAsset = selfHostedGoogleCssByUrl.get(
googleFontStylesheetRelation.to.url
);

// Resource hint: preconnect to the Google font hostname
insertPreconnect(
htmlParent,
googleFontStylesheetRelation.to.outgoingRelations[0].to.hostname,
insertPoint
if (!selfHostedGoogleFontsCssAsset) {
selfHostedGoogleFontsCssAsset = await createSelfHostedGoogleFontsCssAsset(
assetGraph,
googleFontStylesheetRelation.to,
formats
);
subsetFontsToBeMinified.add(selfHostedGoogleFontsCssAsset);
selfHostedGoogleCssByUrl.set(
googleFontStylesheetRelation.to.url,
selfHostedGoogleFontsCssAsset
);
}
const selfHostedFallbackRelation = htmlParent.addRelation(
{
type: 'HtmlStyle',
to: selfHostedGoogleFontsCssAsset,
hrefType: 'rootRelative',
},
'lastInBody'
);

relationsToRemove.add(selfHostedFallbackRelation);
asyncLoadStyleRelationWithFallback(
htmlParent,
googleFontStylesheetRelation
selfHostedFallbackRelation
);
relationsToRemove.add(googleFontStylesheetRelation);
}
relationsToRemove.add(googleFontStylesheetRelation);
}
}
googleFontStylesheet.unload();
Expand Down

0 comments on commit 2782774

Please sign in to comment.