見出し画像

Web FontによるCore Web Vitalsへの影響と使い続ける方法

先日、辻さんの下記ツイートを拝見しました。

私自身も、WebフォントがどれくらいCore Web Vitals影響するのか、影響を回避しながらWebフォントを使う方法がハッキリ分かっていなかったので、調査してみました。

本投稿はWEB上から入手できる情報源をもとに内容をまとめています。情報の正確性には留意していますが、私の独自の解釈・予想も含まれています。以上から、本情報はいち見解として捉えていただきますようお願い致します。

WebフォントによるCore Web Vitalsへの影響とは

Core Web Vitalsの中でも、LCP、CLSの2つが影響を受けると考えられます。

背景

■影響1:最大コンテンツの描画(LCP)

最大コンテンツの描画にかかる時間が、Webフォントによって遅延する可能性が想定されます。

画像4

シンプルなWebページであればCSSやJavaScriptが少ない為、レンダリング処理も限定的であり、WebフォントによってLCPに悪影響をきたす可能性は低いと考えられます。

しかし、多数のCSSやJavaScriptを読み込み実行している中、さらに大きなWebフォントが読み込まれ描画というタスクが入る事で、結果的にLCPの描画にも影響(遅延)をきたす可能性があります。

画像31

また、Google Fontsの早期アクセスVerを利用した事で、結果的にFirst Paintをブロックしてしまう事もあります。

早期アクセスVer:https://fonts.googleapis.com/earlyaccess/notosansjp.css

■影響2:レイアウトのズレ(CLS)

Webフォントが描画されることにより、コンテンツの文字サイズが変わり、レイアウトが移動。結果、CLSのスコアが悪化するケースです。

「Webフォントが影響するCore Web Vitals」と聞いて、真っ先に思い浮かべるのがCLS(レイアウトシフト)への影響です。

スライド2

今回、WebFontとCore Web Vitalsの調査にあたって、デモページを作ってみました。CLSの影響を実際にご覧になりたい場合は下記デモページを御覧ください。

なお、デモページをCSL計測ツール「CLS Calculator」で測った所、0.046でした。

スライド3

CLSの基準値で見れば、0.046はまだ「Good」の範囲内ではあるものの、ページ内のコンテンツ(文章)量が増えればWebフォントによる再描画によってレイアウトシフトがCLSの基準値(Good)を超えてしまうのでは無いかと思います。

---

簡単ではありますが、以上が「Webフォントが影響するCore Web Vitals」になります。

特にCLSへの影響が大きく、その要因として下記が考えられます:

(1) ページ表示後にWebフォントが再描画
 ↓↓
(2) 文字の大きさや幅が変化
 ↓↓
(3) レイアウトが移動
 ↓↓
(4) CLSが悪化

以上から、Webフォントを使いながらもCore Web Vitalsに影響しない為には、上記1~3の発生をいかに防ぐかがポイントとなります。


CWVに影響せずにWebフォントを使う方法

Core Web Vitalsに影響せずに、Webフォントを使い続ける方法は下記の通りです。

スライド6

まず基本方針としては、
①再描画させない
②描画に時間をかけさせない
を挙げました。

WebフォントがCore Web Vitalsに悪影響をきたしてしまう根本的な要因は「文字サイズの変化と、描画にかかる時間」にあります。

この2点をいかに防ぎ、短縮化するかが重要となります。

では、この基本方針をどう実現するのか?そこで立てたのが以下の対処方針です。

背景2

基本方針である
・後から文字サイズを変化させない
・描画に時間かけない
を考えた際、上記の1~3が対処案となりました。

では、各々説明していきます。


【対処1】font-display:optionalを利用する

font-displayとは、Webフォントが描画できるまでの間、どのように表示するかを指定できるプロパティとなり、下記のようにCSSで指定できます。

画像10

現在、「auto」、「swap」、「block」、「fallback」、「optional」の計5つの選択肢があります。

今回、各値の説明は省きますが(詳細→MDN Web Docs)、このfont-displayを利活用する事で「後から文字サイズを変化させない」に対処できます。

■ブラウザのデフォルトは「font-display: auto」

font-displayを指定しない場合、「auto」が適用されます。この「auto」の共同は下記の通りです:

(1) 2~3秒の間、Webフォントの描画を試みる
 ↓↓
(2) 2~3秒以内に描画出来ない場合は、ローカルフォントで表示
 ↓↓
(3) Webフォントで描画できるタイミングで、フォントを変える

上記の流れにおいて、(2)の「一旦、ローカルフォントで表示」が入ってしまう為、(3)の「Webフォントで再描画」の時にレイアウトシフトが発生してしまいます。

スライド8

ブラウザのデフォルト設定である「一旦、ローカルフォントで表示」が、結果的にCLSの悪化を招いている状態です。

※ブラウザごとの対応とタイムアウト時間に関しては「Controlling Font Performance with font-display」を御覧ください。

■「optional」で再描画を防ぐ

「一旦、ローカルフォントで表示 → Webフォントで再描画」がレイアウトシフトを引き起こしているという事がわかりました。

この「再描画」は font-displayの「auto」や「swap」、「block」などが該当し、Core Web Vitalsの観点からはこれら値をfont-displayに設定する事はできません。

では、どうするのか?
ここで利用するのが「optional」です。

font-display: optional の挙動は
・100ミリ秒はWebフォントの描画を試みる
・それ以上時間がかかる場合はローカルフォントで表示
・以上(再描画しない)
になり、基本方針の「再描画させない」にマッチします。

スライド11

つまり、「Webフォントの描画は約束しないが、レイアウトはズラさない」という挙動であり、Core Web Vitalsの面では適切な選択肢といえます。

font-displayによるWebフォント表示の差を実際に体験できるデモページを作りました。

図3

こちらからアクセスし、「auto」、「swap」、「block」、「optional」の違いを御覧ください。

---

font-display: optionalを利用する事で、「Webフォントの再描画」を防ぐ事はできましたが、ここで新たな課題も出てきました。

それは「100ミリ秒以内にWebフォントを読み込み、描画できる状態に無ければならない」という点です。

スライド13

この点を対処しないと、レイアウトシフトは発生しないがWebフォントで表示されない、という本末転倒な状態に陥ります。

そこで必要なのが対処2の「ローディング時間の短縮化」です。


【対処2】ローディング時間の短縮化

font-display:optionalを利活用する為にも、Webフォントのファイルを素早くWebブラウザにダウンロードさせ、いち早く描画できる状態にしなければなりません。

そこで重要になるのが、Webフォントのローディング時間の短縮化です。

英語と比較し、文字数が多い日本語は、当然フォントファイルのサイズも大きくなります。Noto Sans CJK JPのBoldに至っては、14.3MBもあります。

Webフォントのファイルサイズが大きければ、ダウンローディング(読み込み)とレンダリングにも時間を要してしまいます。

実際にデモページを作った所、フォントサイズが軽いWebフォントの方が描画が速い結果となりました。

スライド18

では、このローディング時間を短縮していきます。

■Webフォントを軽量化(サブセット化)

日本語のフォントには、普段あまり使われない漢字などが含まれます。フォント「全部入り」の状態から、日常的に使われるフォントのみを抽出する事で、フォントファイルそのものを軽量化(サブセット化)します。

スライド19

サブセット化する文字は「日本語WEBフォントをサブセット化する際の参考文字列一覧」の「JIS第1水準+常用漢字+その他でまとめると」を利用しました。

図5

サブセットフォントメーカーを使って、Webフォントを軽量化します。

今回サブセット化したNotoSans Boldの場合、13.9MB→0.5MBまで軽量化できました。

画像15

という事は、日常的に利用されないフォントが多数入っている事になります。Core Web Vitalsの観点からも、Webフォントを利用する際は、サブセット化(必要な文字フォントのみを抽出)を検討した方が良いでしょう。

画像29

なお、サブセット化によって軽くなったNotoSansを体験できるデモページを作りました。合わせてご覧ください。

※Webフォントのサブセット化やファイル形式については「Webフォントをサーバにアップロードして使うには?」をご覧いただく事をお勧めします。

■Webフォントフォーマットの変更

メジャーどころのWebフォントフォーマットとして下記4つがあります。

・EOT:IEのみに対応している
・TTF:WindowsやMacで標準的に利用されるフォント
・WOFF:Web向けのフォント
・WOFF2:WOFFの圧縮形式を改善し、軽量化したフォント

「Webフォント」として利用するのであれば、圧縮率の観点からWOFFもしくはWOFF2を利用するのが望ましいでしょう。

web.devの「WebFont format」によると、

・対応しているブラウザであればWOFF 2.0を提供
・大多数のブラウザであればWOFFを提供
・Android (4.4 以下) の古いブラウザにはTTFを提供
・IE9以下の古いブラウザ向けにはEOTを提供

との事。

MDN Web docsによると、WOFFおよびWOFF2に対応しているブラウザと、そのバージョンは下記の通りです:

画像16

ざっと見た感じ、今日よく利用されているブラウザの大半はWOFF2に対応していそうです。

Googleアナリティクスから自分のWebサイトにアクセスするユーザーのブラウザとバージョンを確認できるので、一度対応しているユーザーの割合を確認してみると良いでしょう。

しかし、全てのユーザーに意図した形でWebページを見せたいもの。ブラウザやバージョンによってフォント形式の対応・非対応がある中、どうすれば良いのでしょうか?

解決策として、
・複数のフォントフォーマットを用意する
・CSSでそれら複数フォントを読み込めるように指定する
が挙げられると考えます。

Webフォントは、CSSを通して読み込むフォントファイルやフォーマット、Class名を指定します。

図1

この際、上記のように複数のフォントフォーマットを format(); で指定出来るようになっています。

同じフォントを異なるフォーマットで複数回指定しても、全てが読み込まれる事はありません。ブラウザが自動的に判断し、自ら対応している最善のフォーマットを1つ選んでくれます。

画像20

上の図は、私の環境(PC Chrome 88)での結果です。woff2が指定されている場合はwoffは読み込まず、woff2のみを利用している事が分かります。

<WOFF2の生成>

WOFFコンバータでWebフォントを生成する際、「WOFF2を作成する」にもチェックを入れます。

画像17

実際、Noto Sans CJK JPのBoldを、サブセット化(軽量化)前と後の両方でWOFFとWOFF2を比較してみました。

画像18

ファイルの容量としては10%~15%ほど圧縮できています。

■HTTP/2とファイル分割

ローディング時間を短縮する方法に「Webフォントのファイルを細かく別けて、それらファイルを同時に一度で取得する」があります。

背景

複数のHTTP通信が同時に行えるようになったHTTP/2を活用し、ファイルサイズが大きいWebフォントのダウンロードを速くする方法です。

Google Fontsでは既にこの方法が実装されており、ファイルサイズが大きいNotoSansを100個近くに分割し、HTTP/2で同時送受信しています。

スライド26

---

以上、Webフォントファイルのダウンロードを短縮する方法を解説しました。

しかし、font-display: optionalを利用するには、100ミリ秒以内にWebフォントを読み込み、描画に移らなくてはなりません。

画像23

しかし、この「100ミリ秒」はとても短く、軽量化したWebフォントでもダウンロードに90ミリ秒近くかかってしまいます。(※状況やファイルによって異なる)

HTTP/2とファイル分割によってこのダウンロード時間を短縮する事は可能ですが、とわいえ、ダウンロード→読み込み→描画という3つの工程を短い時間でこなすには、もう一つ重要な対処があります。

それが、対処3の「描画に必要なファイルを先にロードする」です。


【対処3】描画に必要なファイルを先にロードする

いち早くWebフォントの描画に移るには、Webフォントのファイルを優先的にロードする必要があります。

ここで利用するのが preload です。

画像24

上の図は、とある実験ページのHTMLです。

上から
・CSSのリンク
・Webフォントの読み込み(src)
・link="preload"によるWebフォントの読み込み
という順番で記載されています。

以前であれば、ソースコードの上から順にロードされていましたが、現在のブラウザにおいてPreloadを指定した際、その読み込み順はどう変わるのでしょうか?

画像25

案の定、Webフォントのファイルが真っ先にローディングを試みているのが分かります。仕様通りですね。

スライド17

画像など読み込みの対象となるファイルが増えても、Preloadを指定したファイルが優先的に読み込まれます。

軽量化したWebフォントファイルをPreloadで先読みする事で、font-display:optionによる100ミリ秒以内での描画に備えます。

画像27

また、キャッシュとしてブラウザ内に保存されているWebフォントもPreloadを用いる事で先にキャッシュから呼び出し、高速に描画できるようになります。


対処済みのWebページ

こちらのデモページの「キャッシュあり+Preload」をクリックしてみてください。

画像28

非常に最小限の構成で作られたデモページですので、実際のWebページとは事情が異なりますが、
1)font-display:optionalを使う
2)ローディング時間を短くする
3)先に読み込む
を反映した結果、レイアウトシフトを引き起こさずにWebフォントを適用できているページになるかと思います。


Webフォントを使い続ける是非

最後に、SEOの観点からWebフォントを使い続ける是非について、私の見解を書きたいと思います。

結論は下記の通りです:

・Core Web Vitals対応した形でWebフォントを使う事は可能
・しかし、技術的な技能や工数(費用)を多く要する
場合もある
・「デザイン」と「SEO」は相反する場合もある
・「何を最優先したいか」を明確し、利用方針を決める

今回、「SEOの観点」からWebフォントを使い続ける方法を模索しました。ローディング時間の短縮化やPreloadなど色々打てる手はあり、これら手法を通してWebフォントをCore Web Vitalsに対応した形で利用できる事も分かりました。

しかし、同時に「デフォルトのフォントでも良くないか?」とも感じていました。

趣味で作るWebページではフォントを指定する事は殆ど無く、それでもある程度きれに表示されるので、Webページ作りにおいてフォントの重要性を意識した事はありませんでした。

しかし、それは単に私がWebデザインに明るくなく、フォントの重要性を理解していないからでもある、と思っています。

SEO観点でWebページを見た際、フォントよりもページエクスペリエンスやコンテンツ、とりわけ検索意図に対するアンサー度に目が向きます。

しかし、Webページというクリエイティブを通して伝えたいメッセージを表現する「デザイン」という観点では、「フォント」の重要性は私が感じている以上に高いものなのでしょう。

■「デザイン」と「SEO」の両方を満たす実装

では、「デザイン」と「SEO」の両方を常に満たす実装方法があるか?と聞かれると、私自身、まだYesともNoとも言い切れません。

SEOの観点からWebフォントの使用を考えると、再描画によるレイアウトシフトは防ぐ必要がある為、font-display:optional を使わざるを得ないと考えます。

しかし、デザイン面で考えると、出来る限り指定したWebフォントでページを表示させたいものです。そうなると、Webフォントのロードと描画を待ち続ける必要があり、その後に発生する可能性があるレイアウトシフトを容認しなければなりません。

もちろん、optional範囲内(100ミリ秒以内)でWebフォントが確実に表示できれば良いですが、クリエイティブを最優先にする場合であれば、font-display:blockやswapを使う方が適切でしょう。

以上からも、確実にSEOとデザインの両方を満たす実装方法は、まだ無いのではないかと考えています。

■Page Speed Insightの提案

Core Web Vitalsを含めた総合的なユーザー体験を計測するPage Speed Insightでは、Webフォントに関して下記診断を表示する事があります。

画像30

この「ウェブフォント読み込み中のテキストの表示」の詳細リンク先を見るとfont-display:swapの利用が提案されています。

確かに、FOIT対策としては「swap」は正しい選択かもしれません。しかし、swapを指定する事でWebフォントの再描画を許し、結果的にレイアウトシフトを招く可能性があります。これでは、CLS観点で考えるとswapの利用は適切とは言えないでしょう。

また、2020年4月にリリースされたChrome 83から font-display: optional が改善され、レイアウトシフトへの対応がより可能となりました。

font-display: optional の改善
Chrome で font-display の動作方法がいくつか変更されます。
・font-display を optional に設定しても、再レイアウトが発生しなくなります。
・ウェブフォントを十分高速に読み込める場合にフォールバック レンダリングを行わなくてもいいように、フォントのプリロードは(すべての font-display 値について)レンダリングをわずかにブロックできるようになります。
この結果、font-display: optional とプリロードの両方が使われている場合、フォントの交換によるレイアウトの切り替えが起こらなくなります。

※出典:https://developers-jp.googleblog.com/2020/04/chrome-83-xss-cors.html

以上、Page Speed Insightを含め、GoogleおよびWeb.devのドキュメントにおいて、表示速度を優先にするのか?それともWebフォントの描画を追うのか?はたまたレイアウトシフトの抑制を最優先とするのか、Google社内でも議論が拡散している(方針が決まりきっていない)印象を受けます。

■最終的な見解

いろいろ書きましたが、改めて「何を最優先とするか」が重要だと私は考えています。

Webサイトの構築はSEOの観点だけで考えて良いものではありません。事業上、なにを優先するかによって、とるべき観点や施策も変わってくる事でしょう。

例えば、とある単品商品の通販サイトにおいて、その商品の印象やイメージが事業上最も大切なのであれば、SEO以上にデザインを優先するのが望ましく、font-display:swap; や、状況によっては font-display: block; の利用が適正と言えるでしょう。

たとえ、swapによってレイアウトシフトが発生したとしても、事業上デザインの方が重要度が高ければ、デザイン優先で考えるのが最善といえます。

逆に、自然検索流入数が事業収益に大きく影響するとあるECサイトであれば、SEOは事業上の優先度が高く、Core Web Vitalsに対応したWebページ作りが望ましいといえます。

すべての要求・要件に応えることができれば良いのですが、今回のようにSEOと他の要求が相反する場合は、事業上なにを最優先にするかで最終的にWebフォントの利用有無や実装方針を決めるのが良いといえます。

---

以上がWeb FontによるCore Web Vitalsへの影響と使い続ける方法、そして私の見解になります。

ご指摘などあればコメント欄で頂けると幸いです。

お読み頂きありがとうございました。

この記事が気に入ったらサポートをしてみませんか?