この記事は Goodpatch Advent Calendar 2025 15日目の記事です。

はじめに
Goodpatch の運営する ReDesigner で、フロントエンドの開発を行っております、かずです。
ReDesignerが運営するいくつかのサイトでは、フレームワークとして Nuxt を、アイコンとして Material Symbols を使っています。
Material Symbols の利用方法には大きくわけて、SVG と Webfont があります。
本記事では、現在 ReDesignerで採用している利用方法であるWebfontについて、フォントファイルのサイズと、Optical sizeの挙動を確認していきます。
サイズ・挙動確認サイト
早速ですが、転送サイズと挙動の確認用サイトを作りました。(with Claude Code)
このあとの説明などは、このサイトをいじりながらご覧ください。
kazudeath1.github.io github.com
Material Symbols を Webfont で 利用するメリット
Material Symbolsには、Weight Fill Grade Optical size の4つの軸があります。
developers.google.com
Webfontならではの大きなメリットとして、Optical sizeの柔軟な制御があります。
Material Symbolsは可変フォント(Variable Font)として提供されており、font-variation-settingsでアイコンごとにoptical sizeを調整できます。
https://developers.google.com/fonts/docs/material_symbols?hl=ja#opsz_axis
SVGでは各サイズのバリアントを個別にインポートする必要がありますが、Webfontなら1つのフォントファイルでシームレスに切り替えられます。
Webfontのサイズ削減
Webfontは絶対やめたほうがいい?
Webfontについては基本的に避けている人が多いと思います。 フォントサイズが大きいことが主な理由でしょう。
全てのアイコンを収録したフォントファイル(woff2)は、なんと 3.8MB にもなります。
しかし、Webサイト上で全てのアイコンを使うことはまずありませんので、データのほとんどは無駄です。
icon_names とパラメータ指定によるサイズ削減
Google FontsのCDNでは、icon_namesパラメータで使用するアイコンを指定できます。
これにより必要なアイコンだけを含んだサブセットが生成され、ファイルサイズを大幅に削減できます。
さらに、可変フォントの軸(opsz, wght, FILL, GRAD)を固定値で指定することで、不要なバリエーションデータを削減できます。
以下は、opszとFILLのみを可変とし、wghtとGRADはデフォルト値で固定した場合の例です。
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,FILL@20..48,0..1&icon_names=home,search,menu,close,settings&display=block" rel="stylesheet">
FOUT対策
displayパラメータはblockを推奨します。
Material Symbolsは合字(ligature)でアイコンを表示するため、swapを指定するとフォント読み込み中に「home」「search」などの文字がそのまま表示されてしまいます。
blockなら読み込み完了まで非表示になり、この問題を回避できます。(そのかわり、表示されるまでの間は空白になってしまいます)
確認ページでのチェック
以下の確認ページで、Webfontを利用した表示とファイルの転送量を確認できます。
Material Symbols Webfont - 100アイコン

「100アイコン、opszとFILLのみを可変とし、wghtとGRADはデフォルト値で固定」の場合、フォントファイルのサイズは約30KBでした。
SVGとの比較
100アイコンで30KBなので、1アイコンあたり約300byte。
SVG(gzip圧縮後)も1アイコンあたり150〜300byte程度なので、そこまで変わりません。

しかもこの30KBには、
- optical size(20〜48)の連続的なバリエーション
- FILL(0〜1)の連続的なバリエーション
が入ってます。SVGで同じことをやろうとしたら、サイズ違い・塗り違いで複数ファイルを用意することになるので、ほとんど変わらないか、それより大きくなることもありそうです。
初回ダウンロード時の表示遅延にさえ目をつぶれば、JPEG画像1枚程度のサイズを一度ダウンロードするだけで、その後はキャッシュを利用でき、各アイコンサイズごとに適切な表示ができます。この特徴はWebfontの利点といえると思います。
Optical Size の挙動確認
Optical Size によるアイコン形状の変化
次に、確認ページを使って、Optical Size によるアイコンの形状変化を見ていきます。
Material Symbols Webfont - サイズテスト を開くと以下のような画面になります。

Optical size のみを変更してその影響を見たいので、ページ下部の サイズとopszの連動 を size固定48px にし、スライダーをぐりぐりしてみてください。

Optical size の指定によって、アイコンの形状がそれぞれのサイズに適切な状態に変化させることができているのがわかります。
Optical size で定義されている 4パターン 以外のときの挙動
Optical size 自体の有効範囲は 20〜48px ですが、20, 24, 40, 48 のときの4パターンの定義があり、他の数値にしたときにはその補完を取っているようです。Chrome (v143.0.7499.41) でテストすると、途中の数値のときにいきなり変化せず、なめらかに形がかわるのがわかります。

iOS Safari での謎挙動
と、ここまで書いておいて、出かけることになったので、車の助手席でなんの気なしに確認サイトを iPhoneで見たら、謎の挙動を発見しました。
※ 確認環境: iOS 26.1 / Safari

わかりにくいと思うので比較画像を示します。

なぜか opsz が 24 のときだけ突然細くなっています。 なめらかに変化しないというのはなんとも不具合ぽい挙動に見えるのですが、スマートフォンならではの指定があるのか? CSSなどに適切な指定をしていなかったからなのか? 不具合なのか、意図的なのか、現在のところわかりません。
SVGを用いた場合と違い、環境ごとの違いを考えなければならないという点が、Webfontのデメリットの1つかもしれません。
まとめ
今回は、Webfontについて、サイズ・FOUT問題への対応と、Optical sizeの挙動確認を行いました。
結論として、Webfontは使用アイコンを絞ればサイズ的に十分実用的です。100アイコンで約30KB、SVGと同程度のサイズ感でありながら、optical sizeやFILLの連続的な調整が可能という付加価値があります。
optical sizeの恩恵を受けたいならWebfont一択 です。ただし、iOS Safariでの挙動のように、環境差異には注意が必要のようです(震え声)。
確認用サイトに、この記事に使ってないページがいくつかあると思うのですが、元々は、SVGデータを用いた3つのライブラリとも比較し、開発体験を含めた考えを示すつもりでした。時間切れのため次の記事のネタとさせていただきます。
ここまでお読みくださり、ありがとうございました!
Goodpatchでは品質にこだわりたいエンジニアの仲間を募集しています。 少しでもご興味を持たれた方は、ぜひ一度カジュアルにお話ししましょう!