シンプルなアイコンとかロゴとかはSVGが向いていますが、場合によっては重くなるSVGについて確認してみました。
ポイントの数が少ない・オブジェクトの数が少ないものはSVGに向いている
ポイントの数が少なく、オブジェクトの数も少ない画像はSVGにしたときかなり軽量になります。
特にアイコンやロゴのように、比較的シンプルな形を複数サイズで使いまわす場合は拡大縮小が柔軟にできるSVGは向いています。

SVG:332バイト
PNG:2.18KB(2倍のサイズで書き出し)
単純な線形グラデーションの表現も可能
シンプルな画像に、単純な線形グラデーションを付ける場合もSVGで表現可能です。

SVG:553バイト
PNG:2.96KB(2倍のサイズで書き出し)
ポイントやオブジェクトの数が多い場合はPNGのほうが断然良い
ポイントやオブジェクトの数が多くなるとSVGはファイルサイズが顕著に重くなります。
この場合、レンダリング(表示)の負荷も高くなるのでPNGよりSVGのファイルサイズが大きくなる場合は絶対PNGにしましょう。

SVG:684KB
PNG:380KB
ラスター画像を含む場合もPNGのほうが良い
ラスター画像まじりのSVG画像も重くなる傾向です。
そもそもSVGの良さである拡縮自在さが失われるので、ラスター画像が混ざっているときはSVGは避けた方がよいでしょう。

SVG:15.5KB
PNG:8.34KB
SVG画像を使う際は圧縮しておこう


XD上で作成・編集されたパスにはReorient pathをかける
XD上で作成・編集された画像はSVGで書き出すと回転の情報がコード内に表示されますが「元の形で表示させてから回転させる」というのはファイルサイズ的にもレンダリング的にも余分な情報です。
「Reorient Path」プラグインで回転情報を削除してから書き出すとよいでしょう。

https://adobe.com/go/cc_plugins_discover_plugin?pluginId=43ba4fbe&workflow=share
可能ならIllustratorの「単純化」でポイント数を減らす
ポイント数を減らしても表現が損なわれないのであれば、ポイント数は減らしたほうがファイルサイズが抑えられます。

ポイント数 6:332バイト
ポイント数4:273バイト
SVGOなどのSVG圧縮ツールを使うとさらに軽くなる
SVGOというSVG圧縮ツールでコードを最適化すると、ファイルサイズはさらに軽くなります。
https://jakearchibald.github.io/svgomg/
※ただし svgタグからwidthとheightを消すとIE11でめちゃくちゃバグりますのでIE11対応する際は設定にご注意。
そこそこ込み入った画像の場合、実際のレンダリングはどうか?
SVGのほうがファイルサイズが小さくなるが、少々ポイント数やオブジェクト数が多めの画像の場合実際のレンダリングは重くなるでしょうか?
Chrome でNetwork slow 3G & CPU 6x Slowdownという重めの環境を想定してテストしてみました。

リソースのファイルサイズはPNGよりSVGのほうが小さい
リソースのファイルサイズは全体的にPNGよりSVGのほうが小さいようです。

ScriptingとRenderingはSVGのほうが時間がかかる
レンダリングにかかるコストはSVGのほうが大きくなる傾向です。

(未検証)高負荷でもSVGを使いたい部分はどうしたらいいか
デモ程度の量であれば問題ないかと思いますが、それ以上に高負荷になる場合は必ずしもSVGが良いとは言えません。
ただ、拡縮自在なSVGの良さを存分に発揮したいという場合、負荷を軽減するためには該当箇所に backface-visibility:hidden
か transform: translate3d(0px, 0px, 0px);
を当ててやるとよさそうです。
(lottieアニメーションではtranslate3dを当ててGPUレンダリングさせていました)
ただし、不必要な部分にまでこれらを利用すると、逆に負荷が高くなるともいわれていますのですべてのimgタグにつける、というような雑な使い方は避けましょう。
まとめ
- シンプルな形状なら、グラデーションがあっても無くてもSVGは軽い
- 形が同じでもポイント数やオブジェクト数が多くなるほどSVGは重くなる
- 不要なポイントやオブジェクトは消そう
- オブジェクト数が多い複雑なイラストはPNGを検討しよう
- 2倍サイズのPNGよりもファイルサイズが大きくなるならSVGは使わない
- ラスター画像を含む画像はPNGにする
- SVGを多用する場合はレンダリング負荷に注意する
- レンダリング負荷が気になる箇所は backface-visibility:hidden か transform: translate3d(0px, 0px, 0px); による対策も選択肢に
便利できれいなSVGですが、SVG画像のほうがファイルサイズが大きくなる場合もあること、レンダリング負荷が高い場合があることに気を付けましょう!
コメント