Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

font example #215

Merged
merged 8 commits into from
Jul 25, 2023
Merged

font example #215

merged 8 commits into from
Jul 25, 2023

Conversation

davidnuescheler
Copy link
Contributor

@davidnuescheler davidnuescheler commented May 8, 2023

the vast majority of projects load custom web fonts. font loading while preserving a great user experience can be complex and often is dependent on the specific fonts that are being used.
this PR provides an example that should work for most projects, and combines and initial lazy load on mobile, to avoid impact to LCP and loads fonts eager on subsequent pages on mobile. on desktop there is usually more bandwidth so loading fonts early can probably happen without material LCP impact (depending on the font).

there are a number of open questions here:
(1) where should we put licensing terms for roboto
(2) the font-loading sequence should probably be related to bandwidth not screen size
(3) putting roboto into the repo, means that most project will have to remove those files and replace them with other self hosted font files

https://font-example--helix-project-boilerplate--adobe.hlx.live/
vs.
https://main--helix-project-boilerplate--adobe.hlx.live/

@aem-code-sync
Copy link

aem-code-sync bot commented May 8, 2023

Hello, I'm Franklin Bot and I will run some test suites that validate the page speed.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-run PSI Checks

@aem-code-sync
Copy link

aem-code-sync bot commented May 8, 2023

Page Score PSI Audit Google
/ SI FCP LCP TBT CLS PSI
/ SI FCP LCP TBT CLS PSI

@aem-code-sync
Copy link

aem-code-sync bot commented May 8, 2023

Page Score PSI Audit Google
/ SI FCP LCP TBT CLS PSI

@aem-code-sync
Copy link

aem-code-sync bot commented May 8, 2023

Page Score PSI Audit Google
/ SI FCP LCP TBT CLS PSI

@davidnuescheler
Copy link
Contributor Author

at least for boilerplate it looks like there is no discernible performance impact.

Screenshot 2023-05-07 at 6 28 30 PM

Screenshot 2023-05-07 at 6 28 59 PM

@@ -105,6 +109,11 @@ async function loadLazy(doc) {
loadFooter(doc.querySelector('footer'));

loadCSS(`${window.hlx.codeBasePath}/styles/lazy-styles.css`);

loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`, () => {
if (!window.location.hostname.includes('localhost')) sessionStorage.setItem('fonts-loaded', 'true');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why sessionStorage and not localStorage ? If I frequently come back on the site on mobile (and close my browser app), I'll have to wait before the font is loaded while the font is cached already.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading fonts.css a 2nd time on desktop... again, this probably works but not necessarily nice. We could use a global flag to track if we have loaded fonts.css or not. And also set the sessionStorage property in the eager phase too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

localStorage is permanent, by default we cache for 2h for items coming from the code bus which seems much more of a session scope...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think loadCSS() would not add the fonts.css if it is already present, and if it did, the browser wouldn't load it twice either, so i think this is pretty safe.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sessionStorage may throw an exception if quota has been exceeded or user disabled web storage. You may want to wrap in a try catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. i have definitely never done that in the past, but i am not opposed to it.

Comment on lines 73 to 76
if (window.innerWidth >= 900) loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`);
if (sessionStorage.getItem('fonts-loaded')) {
loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is calling loadCSS twice on desktop the 2nd time... browser is probably smart but could be optimised as:

Suggested change
if (window.innerWidth >= 900) loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`);
if (sessionStorage.getItem('fonts-loaded')) {
loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`);
}
if (window.innerWidth >= 900 || sessionStorage.getItem('fonts-loaded')) {
// load fonts.css immediately on desktop or if font has already been loaded
loadCSS(`${window.hlx.codeBasePath}/styles/fonts.css`);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure the extra code is needed given that loadCSS() already checks

@@ -70,6 +70,10 @@ async function loadEager(doc) {
document.body.classList.add('appear');
await waitForLCP(LCP_BLOCKS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not calling the loadCSS before the waitForLCP ? The call is async and not blocker and downloading the css + the fonts could happen while we wait for the LCP to be completed ?
I am just thinking to the case where the LCP is a large text while will be impacted by the font loading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not about blocking but instead about bandwidth constraint... so if you have multiple requests go on in parallel, they will share the bandwidth, in which case the loading of the LCP would take 2x as long.

@aem-code-sync
Copy link

aem-code-sync bot commented May 31, 2023

Page Scores Audits Google
/ PERFORMANCE A11Y SEO BEST PRACTICES SI FCP FMP LCP TTI TBT CLS PSI

@aem-code-sync
Copy link

aem-code-sync bot commented Jul 24, 2023

Page Scores Audits Google
/ PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

@davidnuescheler davidnuescheler merged commit e6399b8 into main Jul 25, 2023
3 checks passed
@davidnuescheler davidnuescheler deleted the font-example branch July 25, 2023 14:07
@@ -70,6 +82,15 @@ async function loadEager(doc) {
document.body.classList.add('appear');
await waitForLCP(LCP_BLOCKS);
}

try {
/* if desktop (proxy for fast connection) or fonts already loaded, load fonts.css */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast connection

It's not widely supported yet but you could use navigator.connection.downlink to get the bandwidth estimate in megabits per second to know if the user has a fast connection or not https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlink

Copy link

🎉 This PR is included in version 1.3.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants