There are four modern font formats:

  1. TrueType (.ttf extension)
  2. OpenType with CFF outlines (.otf extension)
  3. WOFF (web font, .woff extension)
  4. WOFF2 (web font, .woff2 extension)

Although only WOFF, which stands for “Web Open Font Format”, mentions “web”, all of them can be used on the web.

Which File Format to Choose

WOFF format has the same browser support as the TrueType and CFF formats, so I’d say you must use at least WOFF when serving font files to your users.

WOFF2 has slightly less support across browsers, but we can safely assume that this format has been supported in all major browsers since at least Sep 17, 2018 (see Safari). The difference in support is negligible — only about half a percentage point less.

I encourage you to always go with WOFF2 unless you’re developing for Internet Explorer, in which case add fallbacks for WOFF. ttf and otf formats are unnecessary.

If possible, use variable fonts, as they combine multiple weights into one file.

Optimizing

Following Optimizing Web Assets, Part 1, General Ideas, there are four techniques to optimizing web assets, all of them are applicable to font files to some extent.

Minify

It is possible to minify font files by removing unused glyphs from those fonts. For example, if you need font A just for numbers, you can leave only digits from 0-9 and accompanying symbols like ., ,, etc. Tools like FontForge can help with that, although it doesn’t work well with variable fonts.

Usually, we want to use as few fonts as possible, but it’s inevitable to use more of them as your website grows with multiple language support. Some fonts like Google’s Noto Sans provide standalone files for different locales.

In the case of fonts which have multilingual support and are contained in a single file, you can refer to the Unicode Character Code Charts, use FontForge to extract glyphs into separate files, providing them with different filenames.

Compress

WOFF and WOFF2 have built-in compression, so when (if) converting fonts from ttf or otf, those files will already be compressed, so you don’t need to do anything.

Convert

I think it’s best to work with assets in their original form, or with the source, as developers do it with code. Therefore, I encourage you to minify your fonts in their source formats.

Regardless of whether you’ve made the font files smaller or not, if they’re not in WOFF format, you need to convert them. There is a handy CLI tool by Google to convert fonts to WOFF2: woff2. After building and/or installing it, it’s pretty easy to convert fonts now:

for filename in *.ttf; do
	woff2_compress $filename;
done;

Since it’s a single-argument command, it’s pretty easy to remember, use, and incorporate into your flow.

woff and dewoff CLI comes with FontForge on MacOS, and I don’t know of any other good tools.

for filename in *.ttf; do
	woff $filename;
done;

Delay

As mentioned in the Minify section, there is a Unicode Character Code Charts. Developers can use these charts and CSS property unicode-range inside @font-face to load specific font files when specified symbols are rendered on a web page.

E.g., Simplified Chinese (CJK Unified Ideographs (Han)) has unicode range of U+4E00 through U+9FFF. To load font file for Chinese symbols, developers then declare @font-face like this:

@font-face {
	font-display: swap;
	font-family: "Chinese Font";
	src: url("/path/to/font.file");
	font-weight: 300 900; /* if variable font */
	font-weight: 300; /* if not variable font */
	unicode-range: U+4E00-9FFF;
}

If there are multiple ranges of glyphs, such as in Traditional Chinese, developers can declare unicode-range as a comma-separated list of ranges:

@font-face {
	/* ... */
	unicode-range: 
	U+4E00-9FFF, U+3400-4DBF, U+20000-2A6DF, U+2A700-2B739,
	U+2B740-2B81D, U+2B820-2CEA1, U+2CEB0-2EBE0, U+30000-3134A, 
	U+31350-323AF, U+2EBF0-2EE5D, U+F900-FAFF, U+2F800-2FA1F, 
	U+2F00-2FDF, U+2E80-2EFF, U+31C0-31EF;
	/* ... */
}
$ cd ..