website: Serve fonts as individual files.

Upsides:

- Removing the render-blocking fonts.css allows the page to be visible while the
  font is being loaded.

- The original WOFF2 files are smaller than the base64-encoded version in
  fonts.css.

- Browsers may be smart enough to not download fonts that are not needed.

The only downside is that this requires the browser to make more requests - up
to 6 for all 6 font files. But this is not a problem with modern browsers.
This commit is contained in:
Qi Xiao 2021-11-10 23:43:44 +00:00
parent a0959c2273
commit b49523345e
13 changed files with 45 additions and 99 deletions

View File

@ -17,7 +17,8 @@ default: gen
# Generates the website into the dst directory.
gen: tools $(HTMLS)
$(TOOLS_DIR)/genblog.bin . $(DST_DIR)
ln -sf `pwd`/fonts.css `pwd`/favicons/* $(DST_DIR)/
ln -sf `pwd`/fonts `pwd`/favicons/* $(DST_DIR)/
rm -f $(DST_DIR)/fonts.css # clean up leftover fonts.css
# Generates docset into Elvish.docset.
docset: tools $(HTMLS)

View File

@ -67,11 +67,16 @@ func contentIs(what string) string {
what)
}
const fontFaceTemplate = `@font-face { font-family: %v; font-weight: %v; font-style: %v; font-stretch: normal; font-display: swap; src: url("%v/fonts/%v.woff2") format("woff");}`
func newTemplate(name, root string, sources ...string) *template.Template {
t := template.New(name).Funcs(template.FuncMap(map[string]interface{}{
"is": func(s string) bool { return s == name },
"rootURL": func() string { return root },
"getEnv": os.Getenv,
"fontFace": func(family string, weight int, style string, fname string) string {
return fmt.Sprintf(fontFaceTemplate, family, weight, style, root, fname)
},
}))
for _, source := range sources {
template.Must(t.Parse(source))

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,53 +0,0 @@
# Generates fonts.css by doing the following:
#
# 1. Download Source Serif and Fira Mono
#
# 2. Downsize them by only keeping the Latin glyphs (and a few more)
#
# 3. Embed into the CSS file as base64
#
# External dependencies:
# base64: for encoding to base64
# curl: for downloading files
# fonttools: for processing font files
# Subset of glyphs to include, other than ASCII. Discovered with:
#
# cat **.html | go run ./cmd/runefreq | sort -nr
var subset = …’“”
mkdir -p _fonts_tmp
pwd=_fonts_tmp {
@ssp-files-base = SourceSerif4-{Regular It Semibold SemiboldIt}
for base $ssp-files-base {
curl -C - -L -o $base.otf -s https://github.com/adobe-fonts/source-serif/raw/release/OTF/$base.otf
}
@fm-files-base = FiraMono-{Regular Bold}
for base $fm-files-base {
curl -C - -L -o $base.otf -s https://github.com/mozilla/Fira/raw/master/otf/$base.otf
}
for base [$@ssp-files-base $@fm-files-base] {
# For some reason I don't understand, without U+386, the space (U+20) in
# Fira Mono will be more narrow than other glyphs, so we keep it.
fonttools subset $base.otf --unicodes=00-7f,386 --text=$subset --layout-features-=dnom,frac,locl,numr --name-IDs= --flavor=woff2
}
}
fn font-face [family weight style file]{
echo "@font-face {
font-family: "$family";
font-weight: "$weight";
font-style: "$style";
font-stretch: normal;
src: url('data:font/woff2;charset=utf-8;base64,"(base64 -w0 _fonts_tmp/$file.subset.woff2 | slurp)"') format('woff2');
}"
}
font-face 'Source Serif' 400 normal SourceSerif4-Regular
font-face 'Source Serif' 400 italic SourceSerif4-It
font-face 'Source Serif' 600 normal SourceSerif4-Semibold
font-face 'Source Serif' 600 italic SourceSerif4-SemiboldIt
font-face 'Fira Mono' 400 normal FiraMono-Regular
font-face 'Fira Mono' 600 normal FiraMono-Bold

29
website/gen-fonts.elv Normal file
View File

@ -0,0 +1,29 @@
# Download the fonts needed by the website and downsize them by subsetting.
#
# External dependencies:
# curl: for downloading files
# fonttools: for processing font files
# Subset of glyphs to include, other than ASCII. Discovered with:
#
# cat **.html | go run ./cmd/runefreq | sort -nr
var subset = …’“”
mkdir -p _fonts_tmp
pwd=_fonts_tmp {
@ssp-files-base = SourceSerif4-{Regular It Semibold SemiboldIt}
for base $ssp-files-base {
curl -C - -L -o $base.otf -s https://github.com/adobe-fonts/source-serif/raw/release/OTF/$base.otf
}
@fm-files-base = FiraMono-{Regular Bold}
for base $fm-files-base {
curl -C - -L -o $base.otf -s https://github.com/mozilla/Fira/raw/master/otf/$base.otf
}
for base [$@ssp-files-base $@fm-files-base] {
# For some reason I don't understand, without U+386, the space (U+20) in
# Fira Mono will be more narrow than other glyphs, so we keep it.
fonttools subset $base.otf --output-file=../fonts/$base.woff2 --flavor=woff2 --with-zopfli ^
--unicodes=00-7f,386 --text=$subset --layout-features-=dnom,frac,locl,numr --name-IDs=
}
}

View File

@ -467,4 +467,5 @@ td, th {
.dark td, .dark th {
border-color: #444;
}
/* vi: se ts=4 sts=4 sw=4: */

View File

@ -33,10 +33,15 @@
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="{{ rootURL }}/fonts.css"/>
{{ $docsetMode := eq (getEnv "ELVISH_DOCSET_MODE") "1" -}}
<style>
{{ fontFace "Source Serif" 400 "normal" "SourceSerif4-Regular" }}
{{ fontFace "Source Serif" 400 "italic" "SourceSerif4-It" }}
{{ fontFace "Source Serif" 600 "normal" "SourceSerif4-Semibold" }}
{{ fontFace "Source Serif" 600 "italic" "SourceSerif4-SemiboldIt" }}
{{ fontFace "Fira Mono" 400 "normal" "FiraMono-Regular" }}
{{ fontFace "Fira Mono" 600 "italic" "FiraMono-Bold" }}
{{ .BaseCSS }}
{{ .ExtraCSS }}
{{ if $docsetMode }}