Fighting Flashes of Unstyled Text in Single Page Apps in vue - css

FOUT in SPAs using FEFs. That's a lot of odd acronyms. :)
But it's still an issue.
I have a dynamic component which loads a bunch of components which are meant to look in a very specific way. Each would have its own css, and critically, its own specific fonts.
The fonts are the issue here.
What ways are there to avoid this FOUT in this case?
This is my current research on the topic:
Browsers have a mechanism to hide text it detects is styled with a custom font until the font has loaded.
This does not work in vue, because the text isn't loaded yet either for the browser to detect, so when JS puts the text, this browser mechanism isn't triggered.
Might be fixable via SSR, static DOM - browser can now detect. Still might not want - FOIT (Flash of invisible text) arguably worse (no content vs bad content).
This does nothing for dynamic components
CSS is consolidated unless async component.
You do get all CSS imports, but not all fonts until they are used on the page. I.e. it makes a network request for the css import, but not the fonts, until something on the page gets styled with this font. At least it's... quic. :D
WebFontLoader?
A js library by google/typekit, companion to google web fonts.
Possibly can be used to delay component loading until the font has loaded using its events?
Requires things outside the component to know about the font.
No obvious way to reach down and pull out CSS.

Depending on how many fonts you're loading and the size there are a few things you could do.
Call the fonts in the base HTML file (separate from your other CSS) so the browser is aware of them. Then create a hidden div in the parent component with CSS calling the font for the child. This will cause the browser to request the font before the child component is loaded.
Load all fonts separately in the HTML with rel='preload' or rel='prefetch'. I would do this at the bottom of the HTML so you don't block other content.
Load your fonts in the created lifecycle hook using the CSS Font Loading API. I'm not sure how this will work with Google Fonts vs self-hosting.
Create CSS transitions when loading content like a half-second fade to mask the FOUT. This is obviously not a solution but never underestimate the power of smoke and mirrors to influence the way your app feels.
Also, you should try to make use of the font-display (docs) CSS property. This won't solve the problem but it will make the results more predictable.

Related

CSS doesn't block rendering on Firefox Quantum

With Firefox Quantum I noticed a "glitch" on loading the CSS of some websites.
One of these is my company's website:
Or Github too:
In the first one, we have only one CSS file in the <head> section of our pages.
It seems that - only in Firefox Quantum - the CSS doesn't block the render of the page as it should. The rest of the page loads without the CSS for some instants, then the CSS is applied as if it loads asynchronously (but it's not).
Obviously, this behavior doesn't happen in all the websites I visited.
I really have no clue what's going on :)
To summarize information from bug 1404468, the "flash of unstyled content" ("FOUC") usually happens when something asks for information depending on styles before the stylesheets are loaded:
Scripts on the page that force layout/style recalc, that are executed before the stylesheets are loaded.
It's recommended to "Put all your styles in and make sure that any script that asks for layout information comes after them".
Be careful with defer scripts, which may execute before the stylesheets are loaded (spec bug).
An iframe that loads faster than parent page's stylesheets forces layout of the parent page for complicated reasons, described in the bug.
Addons (example) which ask for layout information before the styles finished loading (i.e. on run_at: "document_end"). Firefox 60 (2018-05-09) fixed FOUC with the addons that queried layout using run_at: "document_idle", and a few add-ons were fixed around the same time.
Firefox had a bug causing it on sites with autofocus, notably GitHub. Also fixed in Firefox 60.
Factors that do not cause FOUC by itself, but can increase the chances of it being visible:
Firefox 53 reduced nglayout.initialpaint.delay (which delays the initial painting of a page after it stopped being blocked by stylesheets, assuming the HTML is not fully loaded by that time) from 250ms to 5ms.
If the FOUC-causing stylesheets happen to load before the delay, you won't see the unstyled content. With 5ms it became much less likely.
If the HTML page itself loads slowly, you may see some content jumping around the page with more likelihood.
Slow network combined with the factors above increases the chances of seeing the FOUC.
Finally, it's common to see the fonts on the web page "upgrade" to page-provided web fonts, because they don't block the initial rendering by design.
Quick fix that worked for me (from vrancken.gilbert in bug 1404468):
<body>
<script>0</script>
<!-- Your code ... -->
</body>
(...) if you add a dummy script right after your tag FF will only render the page when the CSS is loaded.
Additionnal info :
If you manage the Content-Security-Policy (CSP) in your application (prevents inline-script), it's necessary to white-list this line :
For example :
In your application :
<script nonce="JwkbSbZ2MYNwp5Adp8Nk">0</script>
In your 'Content-Security-Policy' HTTP Header :
(...) script-src 'self' 'nonce-JwkbSbZ2MYNwp5Adp8Nk'
Ref : MDN

Pagespeed for web icons: Vector, non-critical CSS, and cacheable

My requirements:
Icons will be used "above the fold", including the site-wide navigation header/menu
Page should initially render without waiting for icons to load (i.e. icons are not added to the HTML nor are they part of critical CSS). In other words icons are considered as progressive enhancement, not core functionality.
Icons should be able to be cached, as many will be used on every page
Do not cause too many extra HTTP requests
Possible solutions (and why they may not work):
Webfont
As it's applied using CSS, it will become part of the critical CSS and cause extra roundtrips before the page can render = violation of requirement 2
One SVG file per icon
Causes one HTTP request per icon = violation of requirement 4
Embed SVG sprite and <use> it
Will be embedded on every single page and hence non-cacheable = violation of requirement 3
External SVG sprite
This is the only solution I can think of that provides efficient HTTP requests (only one!), will support caching, and won't be required before the initial content can be painted by the browser. The sprite could be generated easily using something grunt-svgstore but I'm not sure exactly how the rest would work, particularly CSS. Using <object> with an external link sounds plausible for the HTML (assuming a polyfill for IE is used) but then what about icon backgrounds for CSS - reference them by URL?

Is it possible to add web fonts in stylesheet where placement of <link> to stylesheet is unknown?

I am working on changing the styling of pages within a learning platform. The platform allows for the user (me) to use my own CSS to change the styling of pages I myself have created. The problem is that the platform uses som predefined (and unknown to me) CSS before appending their CSS with my CSS. I don't have access to the actual HTML.
Here is the problem: I would like to use web fonts in my CSS. I have therefore been trying to use #import at the start of my CSS. My CSS is appended too late to the predefined CSS for #import to take effect. The only code I can give the system is my own CSS so I can't directly edit the html head to link to the web fonts.
Is there any other way to add web fonts to my CSS with said CSS being the only code I can write? Is it possible within CSS to append links to the html head? The support team of the platform consider this is a bug but don't offer a workaround. It would be nice not to have to wait for an update if possible.

jQuery Mobile stops working if I remove the css file

I'm using jQuery mobile to create a list menu.
I use a 'slide' effect, when you click an element to show the next page.
I was using a css style sheet which had too many design elements.
So I went ahead and removed the stylesheet and instead added the required styling in the html document.
But now the slide effect doesn't work if I click the elements.
If I include the css style sheet, then it starts working again.
Here is the http://jsfiddle.net/r24XY/ code.
The whole reason why you see those cool looking animations is because of that CSS file.
You must have both JQuery Mobile .js and .css library files in order for things to move.
Ripping certain elements out of the library CSS files just to build your own is a bad idea, very bad idea. What if you miss something ? Even if you don't.. what if they release an update tomorrow? You're going to have to maintain a lot of code.
CSS animations (or transitions / transforms) are used in jQuery Mobile and other mobile web frameworks since these are hardware accelerated on certain devices (namely iOS). Thus, removing the CSS file of course removes the animations.

Controlling #font-face Browser Download

When using #font-face in css, the browser loads my page's text before the font, which results in the font jumping from one style to another (from Arial to myfont). When using condensed fonts, for example, the problem is very pronounced visually.
I only want to display the one font that I have chosen with #font-face. What is the best way to do this?
It's called FOUT the best way to handle it in my experience is by using Google's font loader:
https://developers.google.com/webfonts/docs/webfont_loader
Essentially what you do is let the page load normally (during which the body is hidden or styled font blocks are hidden, your choice), once they are loaded a class is added to the body of the page, this triggers the display of the styled fonts.
The script adds these classes so you can style appropriately:
.wf-inactive - failed to load
.wf-loading - during load
.wf-active - loaded fine
The only downfall is that it requires Javascript..
This is a pretty well-known issue in some browsers (Firefox 3.5/3.6, IE 7-9). WebINK has a JavaScript file available which will allow you to work around the problem.
This is known as a Flash Of Unstyled Text and is due, as you mentioned, to the font files loading in tandem with the rest of the page, whose text will be styled with default or fallback fonts until the new font face is loaded and can be applied.
It appears that the best way to minimize the occurrence of this effect is to minimize the time the client spends loading your custom fonts. Two measures you can take to accomplish this are compressing your font files via gZip and specifying your font files for long-term caching by a viewer's browser for subsequent views via a far-future expires header.
If the FOUT is still pretty jarring for your users, you can specify a similarly-shaped font which is likely to be installed on most viewers' machines as a fallback to keep your page size relatively consistent as the custom font loads. For example, for your condensed font, most viewers already have Impact as an available font, or Arial Narrow, both of which adhere to a 'condensed' style.
And if all else fails, you can always style the entire text of your document with color: rgba(0,0,0,0) and use JavaScript to remove that rule at the end of a timer.

Resources