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".
   - 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
Big Faceless Organization             http://bfo.com

Received on Wednesday, 29 April 2020 18:20:00 UTC