KenjiBaheux / css-font-rendering

A proposal for CSS to let web developers control the behavior of font rendering
Apache License 2.0
96 stars 10 forks source link

Default to 'swap' in supporting browsers #17

Closed scottjehl closed 9 years ago

scottjehl commented 9 years ago

As a developer who has spent far too much time working around browsers’ default behavior of hiding text while fonts load, and as a user who regularly experiences the problem, I love the sound of this proposal. It's simple and definitely preferable to the JavaScript alternatives.

However, I would propose that swap is a more expected and consistent default to recommend for browsers that support the font-rendering property, as opposed to auto, which seems to endorse the status quo of hiding page content while fonts load (for 3 seconds or sometimes more. Except in IE, which gets this one right).

Hiding text from the user, even for a short time like 3 seconds, is an odd behavior to encourage when we're actively advocating that sites should render in less than half that time. There are probably cases where a custom typeface is so important that the content should not be available to the user without it, but that seems like the exception.

By defaulting to swap, developers would need to opt-in to text-hiding in the cases where it is necessary, knowing that otherwise fonts will load in a non-render-blocking manner.

Thanks for considering!

maxfenton commented 9 years ago

:+1:

jgarber623 commented 9 years ago

:+1:

ryantownsend commented 9 years ago

:+1:

zachleat commented 9 years ago

:+1:

localjo commented 9 years ago

:+1:

mathiasbynens commented 9 years ago

:+1: Heck yes. Fast by default.

vfalconi commented 9 years ago

:thumbsup:

jolora commented 9 years ago

:thumbsup:

bramstein commented 9 years ago

:+1:

jonsuh commented 9 years ago

+1

benplum commented 9 years ago

:+1:

ashumeow commented 9 years ago

:+1:

thasmo commented 9 years ago

+1

gjdipietro commented 9 years ago

:+1:

macbookandrew commented 9 years ago

:+1:

Aetherpoint commented 9 years ago

:+1:

bhough commented 9 years ago

:+1:

jefflembeck commented 9 years ago

:+1:

zengabor commented 9 years ago

It sounds great but this is a step in the wrong direction. It's worth reading this text from six years ago and the linked articles: http://www.paulirish.com/2009/fighting-the-font-face-fout/ It's not an accident that it was implemented in Firefox and Chrome the way it is. (But WebKit should fall back within a few seconds, that's true.)

Not hiding the text for a few seconds causes not just the flash of unstyled text but can also cause reflows.

scottjehl commented 9 years ago

@gaborlenard: Thanks for the reply. I’m curious if @paulirish still agrees with his early assessment (linked above) today (hey Paul! :) ), but I disagree that hiding text for any duration is a good default for users, particularly when that duration is longer than the time we consider to be reasonable for serving a usable page.

With regards to reflows: I could be wrong about this, but it’s my understanding that even while the text is hidden, it's still occupying the space in the layout that it would occupy if it were visibly rendered with fallback fonts. The reflow happens when there are sizing differences between fallback fonts and the custom fonts that take their place. In that way, a reflow can happen in browsers that hide the text too, and I believe it's a separate concern. Pairing fallback font sizing closely with a custom font seems to be a reliable means of minimizing that problem (font-size-adjust can help). (Again, clarity on that would be helpful from those in the know!)

zengabor commented 9 years ago

I am not sure about additional reflows because of the fallback. This may indeed depend on the differences between the final and the fallback font. Also, I don't know whether the double painting causes additional issues...

However, here are two interesting threads that are quite similar to this one, clever people trying to find solution to this very problem:

  1. https://bugzilla.mozilla.org/show_bug.cgi?id=499292
  2. https://bugs.webkit.org/show_bug.cgi?id=25207
scottjehl commented 9 years ago

Agreed, it has been discussed a lot. 3 seconds is certainly better than 30, but I'd still argue 0 seconds of hidden text is better than 3, and the swap value's behavior of not rendering the custom font after a specified time seems like a nice compromise as well (cache it for the next page visit).

zengabor commented 9 years ago

The default browser behavior of hiding for a few seconds (which could be just 1) is a carefully selected pragmatic approach between the two extremes: it eliminates FOUT in most cases and it solves the "too-long non-visible text" issue as well.

Note that the whole thing is about solving a special case: the font isn't cached yet and the network is slow (assuming the size of the font files are within considerable limits).

If the majority of the visits are coming from returning visitors and/or fast networks then the default browser behavior of 3 seconds hiding is alright. Then this 3-seconds blackout is a very edge case which happens very rarely.

However, if your site mostly serves first-time visitors from slow networks then you as the developer may decide to optimize for this scenario and choose swap. But I don't think swap should be the default.

igrigorik commented 9 years ago

3 seconds is certainly better than 30, but I'd still argue 0 seconds of hidden text is better than 3

FWIW, real-world data from Chrome: image

First, the good news is that the majority of web fonts are relatively small (<50KB). Second, most font downloads complete within several hundred milliseconds: picking a 10 second timeout would impact ~0.3% of font requests, and a 3 second timeout would raise that to ~1.1%. Based on this data, the conclusion was to make Chrome mirror the Firefox behavior: timeout after 3 seconds and use a fallback font, and re-render text once the font download has completed. This behavior will ship in Chrome M35, and I hope Safari will follow.

zengabor commented 9 years ago

Thanks, Ilya, that helps seeing it in context.

Interesting to see that many people are not bothered by the Flash Of Unstyled Text (FOUT). While setting the "timeout" to 0 will fix a special case which happens only rarely (first time visit on a slow network) it re-introduces the problem of the FOUT for normal cases.

Just went to http://www.filamentgroup.com/ in Chrome and clicked around. Windows 7, i5, 8GB of RAM. Cache enabled and everything. Many times I can see FOUT on the page: text appears first in a different font then immediately flashes to the final font while the page layout jumps a little bit. E.g., every time when I click "Our work" and "Code" in the main navigation. This looks quite unprofessional to me.

So filamentgroup.com may give me a fast reading experience on a first time visit on a slow network once but it degrades my experience almost every time I visit it.

igrigorik commented 9 years ago

Interesting to see that many people are not bothered by the Flash Of Unstyled Text (FOUT).

FWIW, I'm not one of them. As in, it really bothers me. That said, I also want to be pragmatic: I think we owe it to the developers to enable font-rendering (and the sooner the better) to allow them to define their own behaviors and override the defaults where its appropriate... What the defaults should be is an orthogonal discussion in my books:

scottjehl commented 9 years ago

Based on this data, the conclusion was to make Chrome mirror the Firefox behavior: timeout after 3 seconds and use a fallback font, and re-render text once the font download has completed. This behavior will ship in Chrome M35, and I hope Safari will follow.

Thanks, @igrigorik. In fairness, I suspect a large share of the frustration with text hiding comes from iOS Safari users (like me!) who routinely wait 10 seconds or more for text to become visible. The designer in me certainly appreciates custom type, but it's rarely more important to me than the content itself. Here's hoping they move to a similar approach to Chrome and FF, at least. I'm glad this feature will allow us to configure things in a way that feels most user-friendly.

In the interest of not holding things up here in general, I'll close this out.

toddparker commented 9 years ago

@igrigorik - that data is really useful but is that all data for a cable connection running desktop Chrome? If my experience running perf audits on sites, custom fonts can add 2-4 seconds the time it takes to see usable text on a 3G connection, not a few hundred milliseconds.

igrigorik commented 9 years ago

@toddparker no, that data was gathered by instrumenting Chrome and analyzing timing data from real-world users+networks (for those who opt-in to allow Chrome to beacon anonymized telemetry).

paulirish commented 9 years ago

That data from from Chrome on Android users, only. I just doublechecked today. ​

zengabor commented 9 years ago

Sorry guys for my unsolicited comments. Just wanted to bring in some balance. :)

Just for the record, I wrote a short article on this topic a few weeks ago (in which I mention both Scott's book and Ilya's presentation): #2 in Three takeaways for web developers after two weeks of painfully slow internet:

2 . On some sites the text was invisible for a frustratingly long time

This was annoying. The text was already there but I couldn’t see it until the relevant fonts were downloaded. This problem only occurs on WebKit-based browsers, which means iOS and old Android browsers. WebKit is overly polite and just waits and waits, prudishly hiding the text until the font is downloaded. In contrast, Internet Explorer is so rude it will show the site immediately with the fallback font, exposing me to the flash of unformatted text (FOUT) when the fonts are applied. The pragmatic solution is Chrome, both desktop and Android (as well as Opera which uses the same rendering engine): they hide the text to avoid FOUT but only for a maximum of 3 seconds. It’s a smart trade-off between the two extremes. Fortunately, these browsers cover the majority of the browser population. But there are still users out there with old Androids and iPhones, like me, who are sometimes on a very slow network and don’t have the fonts cached.

zachleat commented 9 years ago

Where is a better place to continue the defaults bikeshed? I think it’s a worthwhile discussion to have, even if this isn’t the best place to have it.

I think FOUT is kinda like progressive JPEG for text. :)

igrigorik commented 9 years ago

@zachleat good question.. Perhaps a thread on the CSS working group?