Open westonruter opened 3 months ago
I'm thinking about how this would be implemented in practice.
It seems it would rely on calling getComputedStyle()
on the LCP text element to determine the current font-family
. It would then need to get the first font in that list, and then iterate over all of the stylehseets in document.styleSheets
and for all of the styleSheet.cssRules` inside of them, for example:
( textElement ) => {
const cssFontFaceRules = [];
const stripQuotes = ( str ) => str.replace( /^"/, '' ).replace( /"$/, '' );
const computedStyle = getComputedStyle( textElement );
const fontFamilies = computedStyle.fontFamily.split( /\s*,\s*/ );
const fontFamily = stripQuotes( fontFamilies[0] );
for (const sheet of document.styleSheets) {
for (const rule of sheet.cssRules) {
if (rule.constructor.name === 'CSSFontFaceRule' && fontFamily === stripQuotes( rule.style.fontFamily )) {
cssFontFaceRules.push( rule );
}
}
}
return cssFontFaceRules;
}
But note there can be multiple fonts that have the same font-family
name, but just vary in terms of the font-weight
and font-style
:
@font-face {
font-family: "Inter var";
font-weight: 100 900;
font-style: normal;
font-display: swap;
src: url(./assets/fonts/inter/Inter-upright-var.woff2) format("woff2");
}
@font-face {
font-family: "Inter var";
font-weight: 100 900;
font-style: italic;
font-display: swap;
src: url(./assets/fonts/inter/Inter-italic-var.woff2) format("woff2");
}
So when determining the font file to prioritize loading, it would also need to look at the computed style to find the weight and style to determine which variant of the font should actually be preloaded.
Nevertheless, there could also be duplicate @font-face
rules altogether. The above are from Twenty Twenty's style.css
. However, Twenty Twenty also includes the following in assets/css/font-inter.css
:
@font-face {
font-family: "Inter var";
font-weight: 100 900; /* stylelint-disable-line font-weight-notation */
font-style: normal;
font-display: swap;
src: url(../fonts/inter/Inter-upright-var.woff2) format("woff2");
}
@font-face {
font-family: "Inter var";
font-weight: 100 900; /* stylelint-disable-line font-weight-notation */
font-style: italic;
font-display: swap;
src: url(../fonts/inter/Inter-italic-var.woff2) format("woff2");
}
So these two stylesheets are duplicating the @font-face
rules.
The last one encountered should be used since it wins the cascade.
This all depends on the new client-side extension system being implemented in #1373, so this issue is blocked by that.
I suppose a new dependent plugin would be required for this as it wouldn't make sense in Image Prioritizer or Embed Optimizer.
Feature Description
When the LCP element is text, the loading of the font being used should be prioritized. For example, on one of my blog posts (using the Twenty Twenty theme), the LCP element is an
h1
. It has afont-family
style of:The
Inter var
font is loaded via this stylesheet:The
@font-face
rule is:The
font-inter.css
stylesheet is already loaded with highest priority, but the font file is not in the critical path so it is not discovered until after the critical CSS is parsed:To improve performance, this font file should be getting loaded sooner by adding this link:
This allows the font file to start loading the same time as the
font-inter.css
stylesheet:And this will improve LCP.
Note that
h1
is LCP element 5% of the time on mobile, withh2
andh3
being 2% and 1% respectively. Thep
element is the LCP element 9% off the time on mobile.