-
-
Save MarcoHengstenberg/e49f53f68668a8a9c20f to your computer and use it in GitHub Desktop.
| So here's the story: | |
| I have fontfiles locally (which should be considered the ideal thing - no depencies to external font- | |
| or CSS-files). I want them to load as fast as possible and have a "Flash of Fallback Text" on | |
| firstView with no Flash-whatsoever on repeat views. | |
| Currently, in the Magazine, we're using this localStorage-base64encoded-fontfiles pick-pocket trick | |
| in order to have exactly that functionality. We'd still be fine if you had a flash when returning | |
| after your session expired, so sessionStorage is an option: | |
| - flash on first view | |
| - no flashes on subsequent visits | |
| - returning after session expired -> flash | |
| I would like to use `<link rel="preload" />` in order to mimic something like that using the browser cache | |
| and no storage at all - because no JS dependency. With loadCSS as a polyfill for browsers which don't | |
| understand preload yet, this goal is in reach already - or at least I sense it near but can't grab it. | |
| Here the markup I got in my `<head>`: | |
| <!doctype html> | |
| <html lang="en-us"><head> | |
| <meta charset="UTF-8" /> | |
| <meta content="width=device-width, initial-scale=1" name="viewport" /> | |
| <title>Fontloading with fontfiles - Tested</title> | |
| <style>main{display:block;}html{text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga","kern";background:#e5e5e5;}body{font-family:Verdana,sans-serif;font-size:1.125em;font-weight:400;font-style:normal;line-height:1.55;margin:0 auto;padding:1.618em;max-width:630px;color:#353738;background:#fafaf8;}header{margin-bottom:2em;border-bottom:.08em solid #e53b2c;}header a,header a:hover,header a:focus,header a:active{border:none;background:none;}header img{max-width:229px;}header h1{font-size:1.75em;} | |
| /* Font Setting Fallbacks */ | |
| .pnr {font-family:Verdana,sans-serif;}.pnb{font-family:Verdana,sans-serif;font-weight:700;}.pnr{font-family:Verdana,sans-serif;font-style:italic;}.sr{font-family:Georgia,serif;}.sb{font-family:Georgia,serif;font-weight:700;}.si{font-family:Georgia,serif;font-style:italic;}</style> | |
| <link rel="preload" href="/css/page.css" as="style" /> | |
| <link rel="preload" href="/fontfiles/Proxima-Nova-Regular.woff2" as="font" type="font/woff2" crossorigin /> | |
| <link rel="preload" href="/fontfiles/Proxima-Nova-Bold.woff2" as="font" type="font/woff2" crossorigin /> | |
| <link rel="preload" href="/fontfiles/Proxima-Nova-Italic.woff2" as="font" type="font/woff2" crossorigin /> | |
| <link rel="preload" href="/fontfiles/Skolar-Regular.woff2" as="font" type="font/woff2" crossorigin /> | |
| <link rel="preload" href="/fontfiles/Skolar-Bold.woff2" as="font" type="font/woff2" crossorigin /> | |
| <link rel="preload" href="/fontfiles/Skolar-Regular-Italic.woff2" as="font" type="font/woff2" crossorigin /> | |
| <!--[if IE]><link href="favicon.ico" rel="icon" /><![endif]--> | |
| <link href="img/favicon.png" rel="icon" /> | |
| <noscript><link rel="stylesheet" media="all" href="css/page.css" /> | |
| </head> | |
| Then, I'm loading the stylesheet which has the references to the webfonts asynchronously with a dumbed | |
| down script (before `</body>`, which I'll replace with loadCSS as the next step but for now, it's cool like that: | |
| <script> | |
| var ps = document.createElement('link'); | |
| ps.type = 'text/css'; | |
| ps.rel = 'stylesheet'; | |
| ps.href = 'css/page.css'; | |
| ps.media = 'all'; | |
| document.getElementsByTagName("head")[0].appendChild(ps); | |
| </script> | |
| In Firefox (not supporting preload atm) it works. On first view I get a FOUT and on reloading the page | |
| all fonts and the CSS are requested from the cache -> no Flash. | |
| In Chrome, no matter the technique I ALWAYS ALWAYS ALWAYS have a FOIT (INVISIBLE TEXT IS THE WORST!) | |
| and no matter what I do (FontFaceObserver, preload, subresource, sessionStorage) I always have that | |
| experience. | |
| The only way around this, working in browsers supporting the feature, is to prerender the "next" page (in this case the same page) after | |
| the load event bcs then – tadaaa – no Flash. I do this by using another dumbed down script right | |
| after the stylesheet-loading script: | |
| <script> | |
| window.onload=function(){ | |
| var hint = document.createElement("link"); | |
| hint.setAttribute("rel", "prerender"); | |
| hint.setAttribute("href", "index.html"); | |
| document.getElementsByTagName("head")[0].appendChild(hint); | |
| } | |
| </script> | |
| Of course that is completely not maintainable if you got more than two pages you'd have to prerender - so for | |
| the magazine that's a no-go. | |
| Thoughts? | |
| I hope at least half of my ramblings here make sense. | |
| I tried polyfilling preload with loadCSS -> flash | |
| I tried subresource instead of preload -> flash | |
| I tried to ask my Mom -> ... |
Family matters are calling. Going to return to this Gist tomorrow. =)
I agree with Zach, and more importantly preload can't assure you the fonts are fully loaded when you load the styles, you can only do that with FFO nowadays.
I reproduced the case here just out of curiosity. And you're right, the CSS file is not triggered on Chrome, but it is whenever the polyfill kicks in. This can be achieved in the native implementation using onload="this.rel='stylesheet'" on your preload.
Thanks to both of you. =)
Many many thanks for taking the time to help me clear things up here.
So, in the end there is no way to ensure there's no FOIT on subsequent visits apart from using localStorage in combination with data URIs or the technique Zach wrote about in his article. Well... I'll go from there then and see what I can do.
Alright, Github ate one of my comments just now... what I wrote was: great work on researching Webfonts and ways to load them efficiently Zach! I'm trying to follow your posts as closely as possible, so I read the one about critical Fonts already but that new one... wow, those numbers speak a clear language.