RE: Partial loading of fonts

Hi Mike,

Thank you for joining the WebFonts WG and for sharing your experiences with partial font loading.

The WG operates under the following charter (https://www.w3.org/Fonts/WG/webfonts-2018.html) and conducts its work mostly online and via email list (which you’ve already subscribed to). We also have Zoom calls, scheduled on a weekly basis each Monday at 9 am US Pacific / noon US Eastern / 6 pm Central EU time for one hour. We’ve been following mostly bi-weekly call schedule skipping the calls every other week (the next one is scheduled on May 11). This may change in the future, going back to weekly schedule when the activities pick up, but for now the bi-weekly calls seem to serve the WG well. Call info: https://lists.w3.org/Archives/Public/public-webfonts-wg/2020Feb/0005.html


I recently put together a primer for new members covering all prior [fairly recent] WG activities, hope you would find it helpful: https://lists.w3.org/Archives/Public/public-webfonts-wg/2020Mar/0005.html


Welcome to the WG,
Vlad


From: Mike Bremford <mike@bfo.com>
Sent: Wednesday, April 29, 2020 2:20 PM
To: public-webfonts-wg@w3.org
Subject: Partial loading of fonts

Hello all

Myles asked me to join the Webfonts WG and describe the approach we're using for partial download of fonts. It's the same process that's used for partial download of PDF documents (our business area), where it's called linearized loading. But the approach is generic and works for any file-type that can be usefully divided into chunks. We simply use the "Range" header to request the blocks we need.

The request works like this:

  1.  We request the font from the webserver as normal, but including "Range: bytes=0-" as a request header.
  2.  If the response (includes "Accept-Ranges: bytes" AND if it has a valid Content-Length header AND if it has no "Content-Encoding" header), then close the connection after reading a respectable amount of data, but at least enough to include the initial lookup table.
  3.  We then lazily load the blocks we need from the font depending on the tables (or parts of tables) we need, by submitting a request with an appropriate "Range" header. We break the file up into chunks (we chose 32KB), and request the block(s) with the content we need, so that we're not requesting arbitrarily small chunks.
That's all there is - fairly simply, Myles tells me he's been looking into largely the same approach. There are a few aspects to note.

  *   For smallish fonts, the overhead of all this slows things down. We wanted to make the user choose to load fonts this way, so chose an entirely arbitrary approach - changing the protocol from "http" to "http+stream" - for example "http+stream://bfo.com/misc/verylargefont.ttf<https://protect-us.mimecast.com/s/AATTCwpA5KsGo99yh9fT0J>".
  *   It doesn't work with WOFF2, as the entire font is effectively compressed as a single block. It certainly does work with OTF/glyf, and will with OTF/CFF as well - although the organization of the CFF tables isn't as obviously broken into blocks, the approach is format-agnostic. OTF/SVG and OTF/CBDT should be quite effective.
  *   We tried using "idle loader", requesting each block in sequence when there is no other load going on. This is useful if you anticipate needing the whole file at some point in the future. We found this generally wasn't the case for fonts, where you will often never need much of the file.
  *   My knowledge of HTTP headers is frozen somewhere in the late 90's, so the headers I've chosen might not be the best. This won't work with any sort of whole-file compression, so we have to avoid "Content-Encoding: gzip". And there is a hard requirement that the server send the "Accept-Ranges" header, as otherwise you're interrupting a perfectly good request for no benefit. A reliable way to get that header returned is to request a "Range" in the initial request.
  *   I've no idea how HTTP/2 works so can't comment on whether it's still useful.
Our products are all server based so I can't really give a demo - nothing where you can see HTTP headers or get timing information. Hence the writeup here. I hope this is useful.

Cheers... Mike
--
-----------------------------------------------------
Mike Bremford - CTO                   mike@bfo.com<mailto:mike@bfo.com>
Big Faceless Organization             http://bfo.com<https://protect-us.mimecast.com/s/jioMCv2z58h7vKKAIXX3B_>

Received on Thursday, 30 April 2020 00:00:34 UTC