CSSなどにSVG インラインを埋め込む際に極限まで軽くする

更新日


Optimizing SVGs in data URIs

上記のページの翻訳、意訳、まとめです。

SVGはベクターデータを扱っているフォーマット形式の画像で拡大や縮小に劣化することなく表示ができるので、単純なアイコンや背景画像などに使用されています。

新手法

こちらのSVGデータを使って説明していきます。今回用意する通常のSVG画像です。

https://tabler-icons.io/

こちらのサイトから「mood-smile」をお借りします。


  
  
  
  
  

0.余分なスペースと改行の削除

1.ダブルクォートをシングルクォートに置き換える

「"」ダブルクォートを「'」シングルクォートに置き換えます


2.HTMLエンティティエンコードする

複雑でなければ手動でエンコードしてしまいましょう!「<」は「&lt;」に、「>」は「&gt;」に

ウェブ上にはHTMLエンティティエンコードをしてくれるサービスを提供している場所もあるのでそちらでエンコードするのも良さげ。これでSVG側の変換作業は完成!

&lt;svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'&gt;&lt;path stroke='none' d='M0 0h24v24H0z' fill='none'/&gt;&lt;circle cx='12' cy='12' r='9' /&gt;&lt;line x1='9' y1='10' x2='9.01' y2='10' /&gt;&lt;line x1='15' y1='10' x2='15.01' y2='10' /&gt;&lt;path d='M9.5 15a3.5 3.5 0 0 0 5 0' /&gt;&lt;/svg&gt;

3.先頭にdata:image/svg+xml;をつけて表示する

data:image/svg+xml;&lt;svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'&gt;&lt;path stroke='none' d='M0 0h24v24H0z' fill='none'/&gt;&lt;circle cx='12' cy='12' r='9' /&gt;&lt;line x1='9' y1='10' x2='9.01' y2='10' /&gt;&lt;line x1='15' y1='10' x2='15.01' y2='10' /&gt;&lt;path d='M9.5 15a3.5 3.5 0 0 0 5 0' /&gt;&lt;/svg&gt;

あとは表示したい箇所にこのSVG画像コードを乗せるだけで表示されます

.background{
background:url('data:image/svg+xml;<svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='none' d='M0 0h24v24H0z' fill='none'/><circle cx='12' cy='12' r='9' /><line x1='9' y1='10' x2='9.01' y2='10' /><line x1='15' y1='10' x2='15.01' y2='10' /><path d='M9.5 15a3.5 3.5 0 0 0 5 0' /></svg>');
}

ブラウザの対応状況

以外にも古くからブラウザは対応しており、IE9まで美しく表示されます

.background{
background:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJpY29uIGljb24tdGFibGVyIGljb24tdGFibGVyLW1vb2Qtc21pbGUiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZT0iY3VycmVudENvbG9yIiBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgogIDxwYXRoIHN0cm9rZT0ibm9uZSIgZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgogIDxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjkiIC8+CiAgPGxpbmUgeDE9IjkiIHkxPSIxMCIgeDI9IjkuMDEiIHkyPSIxMCIgLz4KICA8bGluZSB4MT0iMTUiIHkxPSIxMCIgeDI9IjE1LjAxIiB5Mj0iMTAiIC8+CiAgPHBhdGggZD0iTTkuNSAxNWEzLjUgMy41IDAgMCAwIDUgMCIgLz4KPC9zdmc+CgoK');
}

SVGをBase64にして表示すると文字数は638文字。新しい手法ですると、こちら

.background{
background:url('data:image/svg+xml;<svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='none' d='M0 0h24v24H0z' fill='none'/><circle cx='12' cy='12' r='9' /><line x1='9' y1='10' x2='9.01' y2='10' /><line x1='15' y1='10' x2='15.01' y2='10' /><path d='M9.5 15a3.5 3.5 0 0 0 5 0' /></svg>');
}

459文字でSVG画像を表示することができました。ウェブ表示高速化貢献にも繋がりますし、これからはSVG画像をBase64にする手法を捨てて新しい手法で表示していきましょう。方法を説明していきます。何も難しいことではありません

新手法

こちらのSVGデータを使って説明していきます。今回用意する通常のSVG画像です。

https://tabler-icons.io/

こちらのサイトから「mood-smile」をお借りします。


  
  
  
  
  

0.余分なスペースと改行の削除

1.ダブルクォートをシングルクォートに置き換える

「"」ダブルクォートを「'」シングルクォートに置き換えます


2.HTMLエンティティエンコードする

複雑でなければ手動でエンコードしてしまいましょう!「<」は「&lt;」に、「>」は「&gt;」に

ウェブ上にはHTMLエンティティエンコードをしてくれるサービスを提供している場所もあるのでそちらでエンコードするのも良さげ。これでSVG側の変換作業は完成!

&lt;svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'&gt;&lt;path stroke='none' d='M0 0h24v24H0z' fill='none'/&gt;&lt;circle cx='12' cy='12' r='9' /&gt;&lt;line x1='9' y1='10' x2='9.01' y2='10' /&gt;&lt;line x1='15' y1='10' x2='15.01' y2='10' /&gt;&lt;path d='M9.5 15a3.5 3.5 0 0 0 5 0' /&gt;&lt;/svg&gt;

3.先頭にdata:image/svg+xml;をつけて表示する

data:image/svg+xml;&lt;svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'&gt;&lt;path stroke='none' d='M0 0h24v24H0z' fill='none'/&gt;&lt;circle cx='12' cy='12' r='9' /&gt;&lt;line x1='9' y1='10' x2='9.01' y2='10' /&gt;&lt;line x1='15' y1='10' x2='15.01' y2='10' /&gt;&lt;path d='M9.5 15a3.5 3.5 0 0 0 5 0' /&gt;&lt;/svg&gt;

あとは表示したい箇所にこのSVG画像コードを乗せるだけで表示されます

.background{
background:url('data:image/svg+xml;<svg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-mood-smile' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='none' d='M0 0h24v24H0z' fill='none'/><circle cx='12' cy='12' r='9' /><line x1='9' y1='10' x2='9.01' y2='10' /><line x1='15' y1='10' x2='15.01' y2='10' /><path d='M9.5 15a3.5 3.5 0 0 0 5 0' /></svg>');
}

ブラウザの対応状況

以外にも古くからブラウザは対応しており、IE9まで美しく表示されます