方向が決まったので、和文のを入れました。指定自体は数行で終わります。ところが入れた直後にトップページを測ると、フォントファイルが 250 個・合計 2.9 MB 落ちてきていました。
和文フォントは文字数が多いので、ある程度大きくなるのは想定内でした。に響く量ではあるものの、書体を入れる以上は避けられません。しかし 250 個は明らかに多い。調べたところ、こちらの指定の仕方が原因でした。
和文フォントは 120 前後に分割されている
配信元は、和文フォントを文字の範囲ごとに細かく分割して配信しています。ひらがな、よく使う漢字、あまり使わない漢字、というように分かれています。ブラウザは、ページに出てくる文字に必要な範囲だけを取りに行く。この仕組み自体は無駄がありません。
問題は、こちらが subsets を指定したことでした。この指定を書くと、フォントを扱う仕組みが分割ファイル全部にの指定を出します。ブラウザは「先に取っておけ」と言われたので、実際に使うかどうかに関わらず全部取りに行きます。
// 変更前:subsets を指定すると、分割ファイル全部に preload が張られるconst sans = Zen_Kaku_Gothic_New({ weight: ["400", "500", "700", "900"], subsets: ["latin"], // ← これが原因 display: "swap", variable: "--font-zen-kaku",});
// 変更後:preload を切ると、必要な範囲だけを遅延取得するconst sans = Zen_Kaku_Gothic_New({ weight: ["400", "700", "900"], // ウェイトも 3 つに絞った display: "swap", preload: false, // ← 和文では必須 variable: "--font-zen-kaku",});| 設定 | preload の数 | 取得ファイル | 転送量 | CSS |
|---|---|---|---|---|
| subsets 指定・4ウェイト | 359 本 | 250 個 | 2,929 KB | 512 KB |
| preload: false・4ウェイト | 2 本 | 145 個 | 1,397 KB | — |
| preload: false・3ウェイト | 1 本 | 122 個 | 1,188 KB | 110 KB |
先読みは、本当に必要な資源に限れば効きます。使うかどうか分からないものまで指定すると、他の読み込みと帯域を奪い合って逆効果になります。和文フォントは、まさにこの罠にはまりやすい対象でした。
ウェイトを減らせた理由
分割ファイルの数は、ウェイトの数に比例して増えます。4ウェイトなら約 480、3ウェイトなら約 360。だから使っていないウェイトを載せると、そのぶん丸ごと増えます。
そこで、サイト内で実際にどの太さが使われているかを数えました。
| 太さ | 使用箇所 | 読み込み |
|---|---|---|
| 400(標準) | 本文の既定 | あり |
| 500 | 8 箇所 | なし |
| 600 | 23 箇所 | なし |
| 700(太字) | 267 箇所 | あり |
| 900(極太) | 97 箇所 | あり |
500 は 8 箇所、600 は 23 箇所しか使っていませんでした。しかも選んだ書体に 600 という太さは存在しません。指定していたつもりで、実際には読み込まれていなかったわけです。
ブラウザは、指定された太さが無ければ最も近いものを選びます。600 を指定した箇所は 700 で描画され、見た目は変わりません。8箇所や23箇所のために1ウェイト(約400KB)を払う理由はないと判断して落としました。
測り方も書いておきます。ブラウザの開発者ツールでも見られますが、自動で何度も測るなら、読み込みの記録から拾うほうが確実です。設定を変えるたびに同じ手順で測れます。
// ページを開いた状態で実行するconst fonts = performance .getEntriesByType("resource") .filter((e) => /.woff2?$/.test(e.name));
({ preloadLinks: document.querySelectorAll('link[rel="preload"][as="font"]').length, fontFiles: fonts.length, fontKB: Math.round(fonts.reduce((a, e) => a + e.encodedBodySize, 0) / 1024),});描画を止めない設定にしておく
この設定は と同じで、1 か所にまとめて書いておくべき種類のものです。残る 1.19 MB も小さくはありません。ただし display: "swap" を指定してあるので、フォントの読み込みを待たずに文字は表示されます。まず端末の書体で表示され、届いた時点で差し替わる。
この指定が無いと、フォントが届くまで文字が出ません。に直接響くので、和文フォントを使うなら必須です。
さらに削るなら、実際に使っている文字だけを含む専用のフォントを自分で作る方法があります。記事が静的なので理屈上は可能ですが、今回はそこまでやっていません。必要になったときの手段として記録に残すに留めました。
書体を1つ入れるだけで、転送量が 2.9 MB も動く。この事実自体が、非デザイナーには意外でした。デザインの判断が、そのまま表示速度の判断でもあるという感覚は、今回はじめて実感したことのひとつです。
そして、この 2.9 MB は入れた直後に測らなければ気づけませんでした。手元の回線では体感できず、見た目も意図どおりだったからです。変更したら測る、という手順を挟むかどうかだけの違いで、気づけるかどうかが決まります。
次回は、この「測って改善した」という話で私が犯した、もっと基本的な間違いを書きます。そもそも測る単位を間違えていました。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。