R note

Gatsbyサイトでのアイコンの設置について考えてみた

Gatsbyで作っているこのサイトのアイコンをどうしようかしばらく迷っていたんですが、結局、SVGのアイコンをassetsフォルダに入れてそのままCSSから読み込むことにしました。アイコンはMaterial Designのを使っています。

このサイトでは補完的な役割のアイコンしか使っていないので、フォールバック用のPNGを設置するのも辞めました。

アイコンをDevToolsで見た画面

アイコン設置の手順

  1. Material DesignからアイコンをSVGでダウンロード
  2. assetsフォルダに保存
  3. CSSで背景として読み込む

たとえば、投稿日と更新日のアイコンは以下のスタイルで表示しています。

.posted::before, .updated::before {
  display: inline-block;
  overflow: hidden;
  margin-right: 0.125rem;
  width: 20px;
  height: 20px;
  text-indent: -9999px;
  vertical-align: middle;
  position: relative;
  top: -0.125rem;
}

.posted::before {
  content: "Noted on";
  background: url(../assets/baseline-event_note-24px.svg) no-repeat 0 0;
  background-size: 20px 20px;
}

.updated::before {
  content: "Updated on";
  background: url(../assets/baseline-update-24px.svg) no-repeat 0 0;
  background-size: 20px 20px;
}

ビルド時にData URIに変換される

Gatsbyでは10KB未満のファイルはビルド時にData URIに変換されるので、以下のように画像データがCSSに書き込まれます。

/* 変換前 */
background: url(../assets/baseline-event_note-24px.svg) no-repeat 0 0;

/* 変換後 */
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xNyAxMEg3djJoMTB2LTJ6bTItN2gtMVYxaC0ydjJIOFYxSDZ2Mkg1Yy0xLjExIDAtMS45OS45LTEuOTkgMkwzIDE5YTIgMiAwIDAgMCAyIDJoMTRjMS4xIDAgMi0uOSAyLTJWNWMwLTEuMS0uOS0yLTItMnptMCAxNkg1VjhoMTR2MTF6bS01LTVIN3YyaDd2LTJ6IiBmaWxsPSIjNzc3Ii8+PC9zdmc+) no-repeat 0 0;

Data URIsのブラウザサポートは問題ないですし、通信回数を減らせるのでページ表示パフォーマンスにも良いですね。

参考

以下、Gatsbyのドキュメントで10,000バイト未満のファイルはData URIに変換されることについて書かれている部分です。

To reduce the number of requests to the server, importing images that are less than 10,000 bytes returns a data URI instead of a path. This applies to the following file extensions: svg, jpg, jpeg, png, gif, mp4, webm, wav, mp3, m4a, aac, and oga.

アイコン管理サービスも考えたけど...

IcomoonとかFont Awesomeあたりを使って管理するのもありですね。制作するサイトごとにアイコン・セットを作っておけば、SVGをまとめてダウンロードできます。

でも、このサイトではアイコンをそれほど使わないし、ローカルのフォルダで管理しちゃったほうが楽な気がしています。オールドスクールな漢字は否めないですけどね。まぁ、なんでもクラウドでやればいいてもんでもないしw

しばらくは上に書いた方法でやってみようと思います。