AIが教えてくれないWebフォント実装の落とし穴|swapとoptional

AI利用について 当サイトでは、記事作成・編集・画像制作等の一部に生成AIを使用しています。掲載内容は運営者が確認・編集しています。

サイトにWebフォントを実装したいとします。
今の御時世ですと、検索して調べるより、まずAIに聞くでしょう。
実際にClaude Codeに新規スレを立てて聞いてみました。

サイトに LINE Seed JPフォントを読み込みたい コード書いて

イエス、マスター

出てきたのが、こちら。

ClaudeCodeの回答

LINE Seed JP は Google Fonts で公式に配信されているので、いちばん簡単なのはそれを読み込む方法です。

1. <head> に追加(HTMLの場合)

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=LINE+Seed+JP:wght@100;400;700;800&display=swap" rel="stylesheet">

2. CSSで指定

body {
  font-family: "LINE Seed JP", sans-serif;
}

WordPress(functions.php)の場合

function add_line_seed_jp() {
  wp_enqueue_style(
    'line-seed-jp',
    'https://fonts.googleapis.com/css2?family=LINE+Seed+JP:wght@100;400;700;800&display=swap',
    [],
    null
  );
}
add_action('wp_enqueue_scripts', 'add_line_seed_jp');

Nuxt(nuxt.config.ts)の場合

export default defineNuxtConfig({
  app: {
    head: {
      link: [
        { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
        { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' },
        {
          rel: 'stylesheet',
          href: 'https://fonts.googleapis.com/css2?family=LINE+Seed+JP:wght@100;400;700;800&display=swap',
        },
      ],
    },
  },
})

補足

  • ウェイトは細字、標準、太字、極太の4種類を入れています。使わないものを削ると読み込みが軽くなります。
  • 商用利用もOKです(SIL OFL 1.1、一部制限あり)。
  • 日本語フォントはデータが大きいため、表示を速くするコツをLINEヤフーが技術ブログで解説しています。気になるなら参照してください。

使っているのがWordPress・Nuxt・素のHTMLのどれか教えてもらえれば、その環境に合わせて調整します。

Sources:

 

これは新規スレを立ててテストしたものです。
ClaudeCodeの回答は間違っていません。

正しいです

100~800まで全てのウェイトを読み込むのはツッコミどころです。
しかしちゃんと、

ウェイトは細字、標準、太字、極太の4種類を入れています。使わないものを削ると読み込みが軽くなります。

「多ければ削れ」と書いています。

さらにClaudeCodeの名誉のために加えます。

日本語フォントはデータが大きいため、表示を速くするコツをLINEヤフーが技術ブログで解説しています。気になるなら参照してください。

ちゃんと注意書きを記してくれています。
LINEヤフーのページも参照してみましょう。

ClaudeCodeの回答は公式の意図を踏まえたものとわかります。

私の回答が正しいなら、もう本記事は終わりですね

ところが、そうはいかないんです。
ClaudeCodeに限らず、まずこんな感じの回答を出します。
そしてコードも正しい。

……でも、これだけでは足りません。

AIの回答には「落とし穴」があるんです

天満川鈴 WRITTEN BY 天満川鈴
スポンサーリンク

FOITとFOUT

font-display: swap;が正解とは限らない

AIのコードでは font-display に swap を指定しています。
Webフォント読み込みでは定番の指定です。

font-display: swap;
Webフォントの読み込みが遅れる場合、先にフォールバック(システムフォントなど)で表示して、後でWebフォントと切り替える指定。

swapはFOITを避けるための手法です

FOIT(Flash of Invisible Text)とは?;
フォントが読み込まれるまでテキストが表示されない現象のこと

swapにしておけば、とりあえずテキストは表示してくれます。
そのため記事を読むには困らないですし、体感も速くなります。

つまり、

AIの回答はFOITだけを捉えるなら正しいです

Webフォント実装にはFOUTも考えなくてはならない

しかし、

Webフォントを実装するにあたってはFOUTも考える必要があります

FOUT(Flash of Unstyled Text)とは?
Webフォントが読み込まれるまで代替フォントを表示し、読み込み完了後にWebフォントへ切り替わることで、文字の見た目が途中で変化する現象。

一言でちらつき。
font-display: swap;では、回線速度やフォントサイズ、フォールバックフォントとの差などによってFOUTが目立つ場合があります。
Webフォントを実装したことがあるなら、少なくない方が経験しているでしょう。

まとめると、

Webフォントを実装するにおいては、FOITとFOUTの両方を考える必要がある

実例:当サイトにWebフォントを実装してみた

此度、本サイトでWebフォントを実装してみました。
以前は高速化の観点からWebフォントを避けてきたのですが。
2018年にGoogle Fontsが日本語フォントへ正式対応して以降、unicode-range を利用して必要な文字を含むフォントファイルだけ読み込む分割配信が使われています。
日本語Googleフォントの読み込みが改善したとのことなので試してみた次第です。

  • 英字:Inter
  • 日本語:LINE Seed JP

今回は「同期」読み込みで実装をスタートさせています。
定番通りswapを指定しています。

まず、Interは問題なく表示できました。
FOITは発生していませんし、FOUTもごくわずかで、これなら使えます。
次いで非同期にしてみたところ、これもOKでした。

次いで、LINE Seed JP。

ちらつきがやばい!

10年前にGoogleフォント試したときと全然変わってない!

同期でこれなら非同期にすればもっと悪くなるかもしれない。
既にスライスで読み込んでるから、サブセット化したところでタカが知れてそう。

サブセット化という手もあります。
しかし第一水準漢字でやるとして、漏れた場合の字体がフォールバック先のままになる。
一字だけ別のフォントというのは見苦しいものです。

使う字だけをサブセット化するという手もあります。
これだとかなり現実的に使えるのはわかっています。

しかし、ほとんど表示する文章の変わらないコーポレートサイトならともかく。
当サイトのようなブログでそんなことはやってられません。

フォールバックを遊ゴシックにしてたせいでCLSもやばい。
当座凌ぎでメイリオに変更したことでマシになりましたが、やはりちらつきそのものは気になります。

なので、一旦は英字のみInterを読み込んで日本語を諦めようかとも思ったのですが。
ChatGPTに質問してみました。

ここまでは自分で試してみたけど、他に何か手はない?

optionalを試してはいかがです?

font-display: optional;
Webフォントを待つ時間を極めて短くし、間に合わなければそのページではフォールバックフォントを使い続ける指定。Webフォントを取得するかどうかも含め、ブラウザ側に大きく判断を委ねる。

※Google Fontsを利用する場合は、URLの &display=optional で指定します。

ざっくり、

うまく読み込んでくれたら儲けもの、という指定です

まあ、遅れてWebフォントへ切り替わるより、フォールバック表示を許容する方がまし
まさに儲けもの精神で試してみたところ、存外にうまくいきました。
さらに非同期も試したところ悪くなかったので採用しました。

最終的には、次の設定で固定しました。

  • Inter:非同期・swap
  • LINE Seed JP:非同期・optional

swapとoptionalはサイト目的・環境で使い分ける

swapとoptionalは、どちらかが正解というわけではありません。

サイトの目的に応じて、環境に応じて正解は変わります

swap は、望んだWebフォントを最終的に表示することを重視します。
その代わり、FOUTが発生しがちです。
一般的にはコーポレートサイト、特にブランディングを企図したサイトに向くでしょう。

optional は、初期表示の安定を優先します。
FOITもFOUTも発生しづらい代わりにWebフォントが表示されなくても諦める必要があります。
テキストさえ表示されれば問題ないサイト、具体的にはブログに向きます。

とはいえ、swapでもFOUTが目立たないならそのままで構いません。
今回の当サイトにしても、

  • 英字のInterはFOUTがほぼ気にならなかったので swap。
  • 日本語のLINE Seed JPは切り替わりが目についたので optional。

と使い分けています。

実際に使ってみて、おかしくないか自分の目で確認してから実装するのが大事ということです

なお、font-displayは他にもオプションがあります(auto、block、fallback)。
本記事ではswapとoptionalの比較が主題なので、他の値は採り上げません。

まとめ:AIの回答の問題

以上を踏まえた上で。
ClaudeCodeの回答における問題は、これです。

FOUTを回避するどころか、その可能性すらClaudeCodeは指摘していません

一般解としては正しい。
でも、実際の実装においては、それぞれの環境を考慮する必要がある。
FOITとFOUTの両方を考える必要がある。
その上で、ユーザーにとっての最適解とは限らない。

決してAIが悪いわけではありません。
前段で紹介したとおり「FOUTなんとかしたい」と聞けばoptionalを返してくれます。

もっと突っ込んで質問してくれないと、私は答えられないです

AIの回答そのものは正しい。
しかし人間の問いの立て方に問題があるから、その人にとって正しい回答であるとは限らない。

まさしく、

AIが教えてくれない落とし穴

と言えるのではないでしょうか?

スポンサーリンク
天満川 鈴のプロフィール画像
WRITTEN BY

天満川 鈴

未経験からWEB業界に入り、現在はWEBディレクターとして実務に従事。要件整理・導線設計・コンテンツ構成などを学びながら、日々改善を重ねています。AIを活用したコンテンツ制作・効率化を強みとし、プロンプト設計を含めた制作フローの最適化にも取り組んでいます。

詳しいプロフィールはこちら

KUSANAGI ON VPS

VPSは、もう「黒い画面」だけじゃない。

「VPSは難しそう」と諦めていませんか? ConoHaのKUSANAGIなら、ブラウザ上の管理画面(KUSANAGI Manager)で、ドメイン設定からSSL発行まで直感的に操作可能です。

コマンド操作なしで世界最速級の環境を構築できる、今の時代の初心者にとっての最適解。私が長年愛用している理由がここにあります。

※当サイト経由で新規申し込みいただくと、特典として1000円分のクーポンをもらえます。

公式サイトで詳細を見る
× 閉じる