- From: Dael Jackson <daelcss@gmail.com>
- Date: Sat, 20 Jun 2015 08:43:43 -0400
- To: www-style@w3.org
Font Loading
------------
- RESOLVED: font-loading control is only an @font-face descriptor,
not a property
- RESOLVED: accept font-display-thing-whatever-loading property
with four values to be renamed later: block | swap |
fallback | optional
- block shows blank, swaps in fallback at 3s, swaps in
real font whenever it loads
- swap shows fallback, swaps in real font whenever it
loads
- fallback shows fallback, swaps in real font if it
loads before 3s
- optional shows real font if it loads from cache
(very short timeout), otherwise shows fallback;
optional allows UA to not continue loading the
font for the next time
====== FULL MINUTES BELOW ======
Scribe: fantasai
Font Loading
------------
TabAtkins: Basic idea is that a font, once you request it, goes
through two periods.
TabAtkins: One is the "blank" period from 0s, which is when you
don't show anything,
TabAtkins: then the "swap period", which is when you show the font
once it's loaded,
TabAtkins: and lastly the "screw it" period, which is when you no
longer try to show the font, even if it's loaded.
TabAtkins: Question was, do you re-layout at the end of the blank
period?
TabAtkins: Yes.
fantasai: No.
fantasai: You lay out the blank page with the fallback font
metrics. If the real font hasn't loaded yet, the swap
period is also using the fallback font, so no layout
change (just visibility of the font change).
fantasai: Re-layout happens when the real font gets used.
ChrisL: What's the value of having the blank period?
TabAtkins: 2 use cases. One is not good, but ppl do it anyway.
TabAtkins: Using icon fonts. Good icon fonts are implemented with
ligatures, so no problem with using a fallback font.
But bad icon fonts, using pictures assigned to arbitrary
letters, those ones shouldn't show anything,
TabAtkins: because otherwise show random letters.
TabAtkins: The other use case is where the particular font is
important, and it's better to show nothing for a little
bit, rather than showing anything.
ChrisL: That second case is very rare. SVG had people arguing that
way, and 10 years later it's still not significant.
Florian: I think it's the default because of icon fonts.
<BradK> Like with a Klingon font?
iank: There's also a case where you know it's going to load in a
reasonable amount of time, so you don't want to show
anything in the meantime.
plinss: wrt icon fonts, that's the case of you never want to
fallback ever.
TabAtkins: Not sure about that.
ChrisL: Why not have a 'none' generic font family? You can put
font-family: Icon Font, none; ?
TabAtkins: I kinda disagree because if the icon never shows up, at
least there's a visible something and you can learn
"p" means "log out" or whatever.
ChrisL: Couldn't you learn about a magic blank space?
TabAtkins: If you limit the blank phase for a small amount of
time, the user is assessing the page, but hasn't begun
really interacting with it yet.
iank: This is what we did in ?, just showing the basic structure
even before we show the content has a huge user benefit.
iank: Facebook does this, for example.
TabAtkins: You get a much better perceived load time.
TabAtkins: Keywords are in question.
TabAtkins: Under my proposal we have block, swap, optional.
TabAtkins: Block sets the thresholds at 3s and infinity -- you
really want that font --
TabAtkins: after 3s show fallback rather than blank, but always
swap in font once it loads.
TabAtkins: Swap sets the thresholds at 0s and 3s -- you show the
fallback font immediately, and don't swap the real font
if it shows up after 3s.
TabAtkins: Assume user has started interacting with page, so it
shouldn't re-layout.
TabAtkins: Optional sets the thresholds at 0s and epsilon.
TabAtkins: Basically only show the real font if it's locally
available (or loaded lightning fast).
TabAtkins: John's proposal had some other keywords.
TabAtkins: Fallback sets the thresholds at 0s and infinity -- use
the fallback, swap in the real font at any point in
time.
ChrisL: Why epsilon?
TabAtkins: Because if you use zero, you'll immediately fall into
"screw it" and never show the font. It still takes
*some* amount of time to check the cache.
TabAtkins: Optional is "Nice font if you have it, not a big deal
if it doesn't show"
TabAtkins: ? mentioned that you could simply not download the font.
TabAtkins: Mobiles are most likely to fail epsilon,
TabAtkins: continually,
TabAtkins: so never show the font.
TabAtkins: So might be useful to have it mean "loading the font is
optional."
plinss: For "screw it" phase, might want to also say "abort the
download."
[TabAtkins adds a column for the four values titled "download",
with checkmarks on blank, swap, fallback, and abort/cancel for
optional"]
ChrisL: So, which of those should you use in the case where you
have a font for a language which you expect the fallback
font not to have any glyphs?
TabAtkins: I think you'd use 'block'.
TabAtkins: Unicode "can't find the glyph" blocks aren't
particularly useful, so showing blank is fine, possibly
better,
TabAtkins: and then you're treating it as a required font.
TabAtkins: So these are block = "super-needed", fallback = "pretty
needed", swap = "kinda needed", optional = "meh".
ChrisL: Essential, important, preferable, and meh.
leaverou: I think we have consensus on "meh".
Florian: We have two more rows on this table. Not necessarily
desirable, but discussed.
Florian: Safari had an infinite blank period.
Florian: Safari sets thresholds at infinity, infinity, yes
download.
Florian: John had another slightly less bad proposal which was...
Florian: Which had very long but not infinite timeout on blank.
TabAtkins: jdaggett's 'blank' keyword is my 'block' keyword.
[TabAtkins completes the table with jdaggett's variant of Safari's
behavior]
Table:
Column 1: Name of Value
Column 2: Timeout for showing fallback instead of blank
Column 3: Timeout for no longer accepting the real font as a
swap-in
Column 4: Whether or not to complete the download (if the
download has timed out)
block | 3s | infinity | yes
fallback | 0s | infinity | yes
swap | 0s | 3s | yes
optional | 0s | epsilons | abort
-----
Apple | infinite | lol | yes
really-blank | ~60s | infinite | yes
fantasai: I think swap should be called 'fallback'.
fantasai: For fallback, if we want to keep it, that should be
called 'swap', because you can swap forever.
Florian: 'optional' is a good name.
TabAtkins: Our proposed name... we proposed font-display.
TabAtkins: That seems to go along with Chris's names.
Florian: jdaggett had font-display-loading (or
font-loading-display).
TabAtkins: Auto is whatever default you feel like.
fantasai: Could just put your preference in the UA stylesheet.
TabAtkins: Auto allows more sophisticated heuristics.
fantasai: OK, that's fair.
fantasai: So, swap and fallback should swap names.
fantasai: I think 'block' is not a great name.
[discussion that ChrisL's naming captures use cases better]
[fantasai points out that understanding what the values do is
valuable]
<andrey-bbg> I like fallback
Florian: We should definitely have swap & fallback in the first
level.
Florian: Block I guess we need, too.
Florian: Optional could defer.
ChrisL: Don't see the benefit.
leaverou: Are we only going to have keywords, not timeouts?
leaverou: What about other countries?
TabAtkins: 3s in this discussion is just "a reasonable time"
Florian: If you're making a mobile browser for crappy networks,
you can set it to 10sec.
leaverou: But if you're shipping for desktop browsers, will ship
the same hard-coded default everywhere.
[discussion of setting this as a UA pref]
plinss: I have a fundamental moral objection to this entire thing
because it's taking what is fundamentally a user
preference and putting it in the hands of the author.
plinss: I'm cool as long as the UA is allowed to ignore the
author's rules on behalf of the user.
plinss: Want to make sure it's clear in the spec that this is a
hint.
TabAtkins: font-hinting! :D
plinss: Even if we give authors the actual timeouts, the UA could
decide to multiply all timeouts by 10.
TabAtkins: I kinda prefer the intentional keywords (ChrisL's list)
TabAtkins: Rather than the behavioral ones.
TabAtkins: And e.g. not block, not treat as mandatory.
TabAtkins: Hierarchy of levels allows you to do some amount of
discrimination.
Florian: Make everything 'should'.
TabAtkins: Would rather be 'must', with exception for exceptional
network conditions.
Florian: And you can limit the scope of the exception.
fantasai: I think we should have a note about networks speeds and
the timeout.
[Discussion of ChrisL's keywords]
[Should avoid 'important' because of !important]
[ChrisL's keywords = essential, important, preferable, optional]
Florian: Wrt property vs descriptor.
Florian: smfr didn't want a property [ because keeping track of
whether a particular element can use a loaded font or not
is unpleasant ]
Florian: Only having a descriptor does not limit the use cases. If
needed you can create two different fonts via @font-face,
use as you want.
RESOLVED: font-loading control is only an @font-face descriptor,
not a property
ChrisL: Swapping out font in some elements not in others is really
weird.
fantasai: Possible but annoying via descriptor.
plinss: There are use cases for it.
plinss: E.g. navigation you want to never be blank, but other
parts allow to be blank for awhile.
<Bert> (Some people name their fonts by their function, such as
"body font", "button font", etc, so it's easy to have
different policies for each, even if they are actually the
same font face.)
fantasai: We're missing smfr, who might be arguing for blank.
fantasai: But Safari could do that via auto.
Florian: This isn't something we want authors to opt into.
Florian: So, do we want to resolve on the first four values,
modulo bikeshedding?
fantasai: Yeah, block is not a great name.
fantasai: I kinda prefer the functional names to the importance
ones.
fantasai: I would want to know if you are going to swap the font
at any point in the future vs. within a timeout.
TabAtkins: UA could do anything.
?: Only for exceptional cases.
Florian: Timeout varies, but behavior unlikely to.
Proposed resolution: have 4 values for font-loading-display-
whatever: block-essential | fallback-important | swap-
preferable | optional
[Waiting for jdaggett and heycame to dial in and catch up before
resolving]
<jdaggett> explanation of values?
<jdaggett> block-essential == sort of like safari now?
<fantasai> no
[Time is spent to find the table from earlier in the minutes]
<Florian> jdaggett: In terms of your proposal, we're taking blank-
fallback and fallback, rejecting blank, and adding
optional and swap from Tab's proposal,
<Florian> jdaggett: and want to bikeshed everything.
TabAtkins: Every keyword controls how long you blank for, how long
you swap for, and then you're stuck in permanent
fallback.
TabAtkins: block-essential does 3s blank, and swaps in until
infinity,
TabAtkins: swap-important does fallback immediately, swaps until
infinity.
TabAtkins: fallback-preferable does fallback immediately, swaps
only up to 3s.
TabAtkins: optional falls back immediately, swaps if it shows up
fast, and could be ditched if it doesn't load quickly.
[jdaggett expresses concerns wrt epsilon]
TabAtkins: You give it enough time to at least load from cache.
TabAtkins: But if you're in an exceptionally slow network, or
otherwise resource-constrained, you can say "screw it"
and not load the font.
TabAtkins: This sets up 4 preference levels for how important the
font is to the page.
TabAtkins: From "you need to display this font, otherwise
everything is terrible" down to "it'd be nice, but it's
okay if not."
jdaggett: Optional will always display the fallback.
TabAtkins: No, it has an effect. If the font has not yet loaded,
optional is basically guaranteed to show the fallback.
TabAtkins: If the font has downloaded and is in the cache, then
you'll use it successfully.
TabAtkins: On devices too slow to load from cache in a reasonable
amount of time, it won't be used.
jdaggett: People who are demanding optional are asking for a
no-reflow solution.
<jdaggett> The people who are asking for optional are looking for
a "no reflow" use of fonts
TabAtkins: That's very nearly what you get. The only exception is
if you start trying to render text, but the font comes
in, then you re-render.
<jdaggett> i.e. either the font is *immediately* available or it's
not.
<dbaron> Yeah, if the people who want 'optional' actually want "no
reflow", then they're not going to get it with this
definition.
<fantasai> yeah
<dbaron> Is that the main use case?
jdaggett: dbaron's point is my question
jdaggett: [...]
* scribe needs to move closer to speaker
dbaron: Do people who want optional because they want no reflow,
because want to avoid performance cost of reflow?
[several ppl say no]
Florian: No, I want it for... It's a font, if you have it, would
be nice.
Florian: In my mind epsilon is ~ 100ms.
Florian: I'm not looking for entirely no reflow at all,
Florian: looking for, if there is a reflow, it should happen so
early in the page that the user hasn't started reading.
Florian: Which is not what would happen with swap.
Florian: After 3 seconds or so, user might have started reading,
then text moves around.
Florian: If font is sufficiently unimportant, as soon as user has
started reading I no longer want to disturb the content.
Florian: 100ms or so, nobody has got far with reading. But if you
have the font available, I'd prefer that.
Florian: If you reflow a little bit, I won't mind.
TabAtkins: You probably won't notice the reflow during that
portion of the load time.
plinss: If the UA has eye-tracking, can even tell whether the user
is reading or not :)
jdaggett: What Florian's describing... I'm not really sure.
jdaggett: If it helps what Google people are looking for,
jdaggett: I think they're looking for no flash ever.
TabAtkins: I don't think that's what they were looking for, but if
it would help I can ask them about it when I get back
to work.
jdaggett: Discussion with Google people would be nice if not in
various Google forums.
TabAtkins: It generally was, mostly in github for original
proposal.
<jdaggett> It would help if the discussion by Google people was in
public forums like www-style and not within github
issues for example.
fantasai: Interesting thing that was discussed for optional was,
with limited network, just not even bother trying to
load the font.
Florian: Also low memory.
fantasai: And bandwidth constraint.
heycam: ...
heycam: In terms of bandwidth constraint...
heycam: Aren't you going to do the same kind of loading?
heycam: I'm not sure how optional helps with bandwidth constrained
situations.
heycam: Aren't you just going to do the same loading?
fantasai: We had discussed making 'optional' make the loading
optional entirely.
fantasai: So a device that knew it was constrained could opt to
not download the font.
jdaggett: I'm not sure if optional is being imagined in this
context.
jdaggett: On a certain device you have an idea of your max
bandwidth,
jdaggett: you can guess whether going to make it within a certain
timeout value,
jdaggett: there's sort of a multiple-page ...
jdaggett: How are you imagining the font ever gets down to the UA
unless you've got something that says "here's when a
load happens"?
jdaggett: This gets into resource hints.
TabAtkins: When the font is marked optional?
jdaggett: If it's marked optional, how is it ever getting
downloaded?
jdaggett: UA knows it can't download within the timeout, so
wouldn't bother downloading.
jdaggett: Would need some language, something like a resource hint.
TabAtkins: Yes.
TabAtkins: Point is, optional is the least necessary font.
TabAtkins: If UA determines that it will never be able to pull
down reasonably, fine.
TabAtkins: If doesn't have it yet, but bandwidth is fine, then
could continue downloading even though not using it.
jdaggett: Then need a normative definition of whether loading
follows through,
jdaggett: or treated as something that can be ignored.
fantasai: He wants the last column in the table normatively.
TabAtkins: Yes, that would be in the normative definition.
(last column is whether to download or not)
jdaggett: Need to say whether fetch continually or fetch never
happens.
TabAtkins: It might continue or might never happen, depending on
UA.
plinss: I'm questioning how this interacts with service workers.
jdaggett: If different UAs are making different decisions,
jdaggett: optional will be either never use this font or use in a
blue moon.
TabAtkins: Yes.
TabAtkins: If font was important, you'd use a higher-preference
keyword.
TabAtkins: You can just use sans-serif, it's fine.
fantasai: Might want "continue through and download the font" as a
separate switch from the timeout?
TabAtkins: If the font is at all important, so continue
downloading.
plinss: ... service workers could abort the load, or fetch for
next time.
TabAtkins: Would have to talk to other engineers, but this might
have useful conceptual overlap with client hints.
TabAtkins: Could say that optional request is tagged with a
particular client hint.
plinss: In general, we want to try to explain these behaviors in
terms of other API.
fantasai: I suppose might want a user preference to choose not to
download preferable or optional fonts, but download
essential ones.
jdaggett: Don't think I can follow the description.
TabAtkins: Proposal is just your proposal, minus blank, plus my
swap and optional keywords values.
plinss: John, we were very close to accepting this proposal with
strong consensus in the room. Held off because wanted to
give you a chance to object.
plinss: Suggest, if it's okay with jdaggett, that we resolve to
accept this, let TabAtkins write it up as spec prose, and
you can suggest improvements, and we will revisit
<Florian> +1 to plinss
jdaggett: I don't know what the proposal is, can't hear anything
to what TabAtkins says.
jdaggett: I'm fine with Tab writing it up, resolving to move
forward can't tell one way or another.
RESOLVED: accept font-display-thing-whatever-loading property with
four values to be renamed later: block | swap | fallback
| optional
- block shows blank, swaps in fallback at 3s, swaps in
real font whenever it loads
- swap shows fallback, swaps in real font whenever it
loads
- fallback shows fallback, swaps in real font if it
loads before 3s
- optional shows real font if it loads from cache (very
short timeout), otherwise shows fallback; optional
allows UA to not continue loading the font for the
next time
<BradK> What about a descriptor that says what the average
character width and extent is, so that reflow will be
minimal when the font does load?
<ChrisL> bradk, we tried that with css2 (not 2.1) and dropped in
for css3
<ChrisL> bradk - see
http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#synthesizing
<BradK> ChrisL: dropped because to complex? I was think of a
single width (average of all characters), and assuming an
ascender and descender's effect on height, if any.
<ChrisL> bradk - even the more complex one was not enough to
prevent reflow. and that was before opentype features
meant that reflow was even less predictable just from
individual widths
<ChrisL> ... a single average width will not be enough to avoid
reflow
<BradK> ChrisL: didn't mean to synthesize, just as a hint for
reserving space. But OK, I see your next comment there
<jdaggett> bradk: better way is to use font-size-adjust since this
will push the fallback font to be close to the
downloaded one
<BradK> jdaggett: yes, I'd like something like font-size-adjust
for widths, so that when I have a very condensed font, the
fallback don't won't be huge looking.
Received on Saturday, 20 June 2015 12:44:12 UTC