Re: [css-fonts] Proposal for standardizing font timeout behavior

On Thu, Oct 30, 2014 at 1:43 AM, John Daggett <jdaggett@mozilla.com> wrote:

> > Cache lookups are not free or instant, and from first hand experience in
> > Chrome, we can't count on font being available in time just because its
> > "cached"... There are cases where network fetches are faster than cache
> > lookups -- crazy, I know.
>
> With 'optional', the font generally won't be available the first
> time it's referenced, it'll only be *possibly* available on
> subsequent pages, subject to all the lovely browser internals you
> describe.
>

Not necessarily. Layout time != Paint time.. there is a time delta in there
where the request may be satisfied. Also, if you're reusing the same
renderer then you should already have the font in renderer's memory
cache... So, optional is still relevant.

My larger point here is that we should not assume that "local" ==
"instant", or "remote" == "slow". There are cases where we can fetch the
resource really quickly, but I/O is not free either, and sometimes a
network fetch can be very fast. As a result, we should set a deadline on
the request, irrespective of how its fetched, and race it until we're ready
to paint the text.


> > > The Font Loading API gives authors complete control over when fonts
> > > are loaded, precisely when they are used, and how the "swap" occurs.
> >
> > Loads are not instant. Yes, we can kick off a .load() with Font Events
> API,
> > but that doesn't mean it'll complete in time for layout+paint.
>
> The Font ****Loading**** API allows you to kick off the load. Fonts
> can be loaded without being added to the FontFaceSet, so they will
> be unavailable to layout. Authors can hide elements until a font
> is available.


Yep. That's "mandatory", and there are cases where this strategy is
unacceptable -- we want fastest text rendering possible.

On a timer, script can determine whether the font is
> loaded or not and choose to use the fallback font at that point. Or
> it can wait until the font is loaded and decide the most effective
> way to handle the transition to the newly loaded font.
>

This is the crux of the problem.. you can't implement optimal text
rendering with a timer.
- if your timer fires before element's layout, you're forcing the fallback
too early.
- if your timer fires after element's layout, you've delayed text rendering.

Given that layout time for the element is a moving target, based on device,
network weather, browser, etc, there is no way for me to set a timer value
that can resolve both of the above conditions. That's why I want to defer
this to the UA: I'll tell you my policy, you apply it when the time is
right.


> Fonts are needed for layout, so there aren't any separate decisions
> to be made at paint time.
>
> > However, even with the JS event, defining this behavior would still
> require
> > quite a bit of JS work on behalf of developer. Personally, I'd still like
> > to see this as a CSS property. Text rendering (aka, communicating actual
> > information on the page) is the bread and butter of the web... It would
> > sure be nice to make delivering a performant text rendering experience
> > simple.
>
> Just to be clear, what's been proposed doesn't actually affect text
> rendering *performance* in any way. It's simply trying to ameliorate
> the effects of poor load performance for fonts on the dynamic layout
> of the page.
>

Well, if we had instant fetches for every resource, then yes... life sure
would be simple. Sadly, laws of physics still apply, and we have to design
the platform to account for this.


> I should point out here that the ability to set timeout-sensitive
>
behavior on elements is fraught with problems. Consider the example
> of a large document (think HTML5 spec) that uses a downloadable font
> for headings:
>
>   @font-face { font-family: myfont; src: url(myfont.woff); }
>
>   h4 { font-family: myfont, fallback-serif; font-rendering: swap 3s; }
>
> The user agent starts the font load and lays out the first section
> of the document. Headings appear in the fallback font. Because it's
> a large document the font load takes more than 3 seconds, so
> headings in the first section remain in the fallback font. But as
> later sections are laid out, the font *is* available so in those
> sections headings appear in the downloadable font.  But scroll back
> up and the headings remain in the fallback font.
>

This seems like an implementation issue. Personally, I'd expect the
previous headings to be re-rendered with the desired font.


> CSS properties have an initial value which is the same across
> browsers. The descriptors of the @font-face value have default
> values which are the same across browsers. So you need to define an
> initial value of the 'font-rendering' property and a default value
> for the 'font-rendering' descriptor within @font-face rules. In
> fact, to implement what you've described you need slightly different
> values for the property, since I think you want the default value
> for the descriptor to be "whatever the user agent timeout policy is"
> and for the *property* you want an initial value of 'auto' to mean
> "decide based on the 'font-rendering' descriptor value of the font".
>

Gotcha, thanks for the context. However, as Brad mentioned.. couldn't this
be set via UA stylesheet?


> I think the additions proposed don't really address the underlying
> problem (font loads happening late or taking too long) and have some
> unfortunate side effects.


There is no solution for "taking too long" -- we can't change the laws of
physics. Disk+Network latency is a fact of life, and we need to design APIs
that have to work around these limitations.


> I think the Font Loading API provides a
> lot of ways authors can address problems associated with slow font
> loading. I'm not really convinced that twiddling timeout behavior
> via CSS is the right solution here.
>

I think we may be going in circles... :)  I agree that Font Loading API
helps, but it does not solve the problem of racing font fetch and
layout+paint.. that's what this proposal is about.

On Thu, Oct 30, 2014 at 8:23 AM, Tab Atkins Jr. <jackalmage@gmail.com>
 wrote:

> On Thu, Oct 30, 2014 at 1:43 AM, John Daggett <jdaggett@mozilla.com>
> wrote:
> (snip) The Font Loading API is indeed an all-purpose
> solution to any desire for control over font-loading,


Wait, wait.. this is the crux of it.. it's not! There is no way to control,
or accurately guess with a timer, the strategy for using fallback/waiting
for font when UA is ready to layout+paint a particular element. Perhaps I'm
using poor language to explain this... if so, apologies!

font-rendering works together with Font Loading API:
- FL initiates early fetch
- font-rendering tells the browser which rendering strategy it should apply
when its ready to paint+layout (depending on current state of font fetch)

(apologies if I'm repeating myself a few too many times)

On Thu, Oct 30, 2014 at 11:18 AM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 10/30/14, 1:32 AM, Ilya Grigorik wrote:
>
>> I don't think variability is the problem... I'd kick off my font request
>> as soon as possible
>>
>
> There are some issues here in that you don't know whether the font will be
> needed at all until fairly far down the layout pipeline.
> So your options are to do unnecessary loads or to do loads once you know
> you'll actually need the data...
>

Yes, that's true.. you have to be careful with what you preload. The right
solution is to defer as much as possible to the browser (aka, use current
lazyload behavior), and use a "fetch this immediately" override for
resources you are certain that you will need - e.g. I *always* use this
icon font / this character range, etc. As with any optimization.. use
judiciously, measure, etc.

ig

Received on Thursday, 30 October 2014 22:04:54 UTC