W3C

WOFF 2.0, the inside scoop

Today, WOFF 2.0 is a W3C Recommendation. Perhaps you have some questions: what is it, why should I care, can I use it already?

Introduction

WebFonts – fonts which are automatically downloaded and used on demand to render a web page, without having to be installed – have risen in importance in recent years. In 2010, a survey of the top 10,000 websites found that only 1% used WebFonts anywhere on the site. That survey is being repeated twice a month, and today, eight years later, 70% use WebFonts.

Work on the original WOFF 1.0 was started in 2010, at which time WebFonts were barely used. WOFF is a container for TrueType and OpenType fonts; the original font data plus a header and optional metadata (such as the name of the designer, a link to a license) are compressed using the same gzip compression used by PNG images. WOFF 1.0 took a minimum viable product approach, using a compression library that was already in the browser. WOFF 1.0 became a W3C Recommendation in December 2012, at which point WebFont usage had risen to 14%.

By the start of 2014, WebFont usage had risen to 35% of websites. With such a volume of data, improving the compression was seen to have significant benefit. A two-stage compression was investigated: firstly a font-specific data reduction, then an improved general compression algorithm.

WOFF 2.0 Font-specific Preprocessing

TrueType and OpenType are designed more for ease of access than for minimal filesize. Data is often padded to an integral number of bytes, making it faster to access. Sometimes the same or similar information is stored at multiple places in the file, for historical reasons. Some data, such as pointers to glyph outlines, is convenient for access but could easily be recalculated. WOFF 2.0 therefore starts by removing redundant or recalculable data, and packing it into the minimum number of bits. This is based on the MicroType Express technology from Monotype.

To take one example,  the bounding box of a single glyph is defined by four numbers (Xmin, Xmax, Ymin, Ymax). The left side bearing is also stored, and is always identical to Xmin. WOFF 2.0 therefore throws away the left side bearing when the font is compressed, and copies over the value from Xmin when the font is reconstructed.

Not all experiments were successful. For example, the placement of knots in a glyph path follows a set of rules, which can (for example, at local curve minima or maxima) allow a point to be predicted based on nearby points and the overall position on the curve. A novel preprocessing stage was considered which removed predictable points before entropy compression, and restored them in the reconstruction step. Experiments showed that a modest reduction in filesize could be obtained, but that the prediction capabilities of the entropy coder were already accounting for these points and thus, the size of the compressed result was not significantly reduced.

WOFF 2.0 compression (entropy coding)

Several options were examined for the second compression stage. One option, LZMA, gave good results but the decoding time was high, which would have been a problem on lower powered devices such as mobile. For this and other reasons, LZMA was abandoned in favor of a novel compression scheme, Brotli. This was first created, and then further developed over the next couple of years, by a Zürich-based expert compression team at Google, and gives excellent compression results; the decompression speed and the memory need to decompress are also very close to what WOFF 1.0 requires.

During development, WOFF2 was tested on three large datasets: the entire Google fonts corpus (1.1k TTF fonts), the Monotype corpus (33k TTF fonts), and the Adobe Fonts corpus, comprising 13.9k TTF fonts and  5k CFF (Type 1)  fonts. This allowed us to not only measure the average compression, but also to examine the best and worst cases. It is worth noting that the WOFF 2.0 size was smaller than the WOFF 1.0 size, for every font tested. Overall, for Truetype fonts (TTF outlines) WOFF 2.0 is 27% better than WOFF 1.0, and for fonts with Type 1 glyphs it is 13.5% better.

In fact, the general-purpose Brotli compressor is so good that it was also adopted into HTTP, providing benefits to the Web for HTML, CSS and Javascript files as well.

WOFF 2.0 and the future

During the development of WOFF 2.0, new font capabilities arose. Multicolored OpenType fonts, and OpenType Variable Fonts are the two main examples. Both are handled by WOFF 2.0 without change, because it is designed to be forwards compatible.

Using WOFF 2.0

WOFF 2.0 is already supported by recent versions of all the major browsers, and has been for the last couple of years. Fallback to WOFF 1.0 for older browsers is easy, a few lines of CSS and no server-side configuration is required:

/* load WOFF 2.0 font if possible, otherwise use WOFF 1.0 font */
@font-face {
  font-family: ExampleName;
  src: url(example.woff2) format("woff2"),
       url(example.woff) format("woff");
  }

Further reading

3 thoughts on “WOFF 2.0, the inside scoop

  1. Chris, I’d suggest adding “local” as the first source line, which allows for the possibility that the user has this particular font installed on their system already. For example, I have Open Sans, Roboto, the Noto family, Source Code Pro, some of SIL’s fonts, etc. all installed locally. Your code would have my browser download them, which would be a waste.

    So the modification looks like:

    font-family: ExampleName;
    src: local(ExampleName),
    url(example.woff2) format(“woff2”),
    url(example.woff) format(“woff”);
    }

    Speaking of fonts, this W3C blog is brutalizing Windows users with Arial. Your font stack is Mac-centric and reads:

    “‘Helvetica Neue'”, Helvetica, Arial, Verdana, Geneva, sans-serif

    This is frustrating cultural bias in American web development. Most of the time, the nonsensical font stack comes from Bootstrap, but this one looks different. Windows users have many, many fonts. It’s not an Arial-only OS or anything like that. You can assume that most Windows users have Calibri installed, for example, a sans that looks much nice than Arial.

    And there’s no point in listing Arial, since every browser’s default sans, so the final “sans-serif” statement will trigger Arial in those rare cases where the user had none of the other fonts installed. (I’d also use a serif for body text, not a sans, and for Windows users I’d put Sitka Text in the font stack ahead of Georgia. MS introduced Sitka family in Windows 8.1, so it’s on a lot of PCs at this point, given Windows 10’s market penetration.)

  2. Hi Joe,

    Your first point is well made, and in a longer blog I would have mentioned that (though I would also point out that this is a design choice; if the designer wishes to ensure that the particular version of a font is used, for example if they depend on OpenType features which were only added in later font revisions, they would omit the local().)

    As to your second point (cultural bias and USA-centrism) you are unfortunately correct.

    Your third point about the specifics of Windows fonts and font stacks is totally correct and I will pass this on the the people who maintain the stylesheets on our blogging software.

    BTW the default sans on Android is likely to be Droid Sans or Roboto, I suspect, while if there are still any Windows Phone users they will get Segoe UI.

Comments are closed.