Created
March 23, 2016 16:02
-
-
Save MarcoHengstenberg/e49f53f68668a8a9c20f to your computer and use it in GitHub Desktop.
Something about loading webfonts in different browsers and issues I encountered
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 -> ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.