くらしのマーケット開発ブログ

「くらしのマーケット」を運営する、みんなのマーケット株式会社のテックブログです

SVGスプライトの実装方法

はじめに

みんなのマーケットでデザイナーをしているミソサクです。

オフィスには猫が2匹います。ジャンゴ(♂)と、シー(♀)です。私のデスクにはシーちゃんがよく来ます。みんなのマーケットに入社時から2年半くらいコツコツおやつをあげたり「ケツトントン」をしてやっと友達として認められました。とっても可愛いです。だけどズルい女。

仰向けで寝るシーちゃん

先日SVGスプライトを使ったので、実装方法をざっくり書きます。

SVGスプライトとは

アイコンやロゴなど、複数のSVGデータを1つのファイルにまとめて、使いたいデータだけ呼び出す方法です。

なんで今SVGスプライト?

ずばり、スマホページの表示速度改善のためです!「写真」としての役割の画像はいいとして、「アイコン」や「あしらい」としての役割の画像について、くらしのマーケットでは形式がバラバラでした。

  1. jpg
  2. gif
  3. png
  4. svg
  5. 外部Fontファイル
  6. オリジナルFontファイル

そして20回も30回もサーバーにリクエストをしています。

最近追加したアイコンは、IcoMoonを使ってオリジナルFontファイル(上記6)1つにまとまってたんですが、ネットワークが遅いと一瞬文字化けするのが個人的に許せませんでした。ということで、最初に用意する工数は増えるけど最速でアイコンを表示できそうなSVGスプライトにしました。

達成したいこと

全ての画像(写真を除く)において

  • リクエスト数を1にする(表示速度改善)
  • cssで拡大縮小可能にする(ベクターデータにしてRetina対応)
  • cssで色指定できるようにする(色変更のために作り直したくない)

仰向けでこっちを見るシーちゃん

はい、では実装

実装

(1)SVGの準備

サイト上のすべてのアイコンを洗い出します。cssだけで表現できる画像は削除してコード化します。イラレで必要なアイコンを書いて、SVGで保存。軽量化が目的なので、書き出す時は「Illustratorの編集機能を保持」のチェックは外します。

くらしのマーケットロゴデータ

(2)SVGを一つのファイルにまとめる

まとめ役のファイルall-icons.svgの記述

<svg display="none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        // ここに各SVGコードを書く
    </defs>
</svg>

<defs></defs>の中身、各SVGコードの記述

<symbol id="logo" viewBox="0 0 24 24">
    <path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
</symbol>

お察しの通りidは呼び出す時に使います。fill属性の記述は削除してcssでの色指定を可能にします。

(3)表示する

召喚の呪文

<svg class="icon-logo">
    <title>くらしのマーケット</title>
    <desc>くらしのマーケットのロゴです。</desc>
    <use xlink:href=“/path/to/all-icons.svg#logo"/>
</svg>

#の後に呼びたいデータのid名を書きます。

(4)cssで色やサイズを指定

.icon-logo {
    fill: #fff;
    height: 24px;
    width: 24px;
}

色の指定はcolor ではなくて、fillです。

基本的な使用方法は以上ですが、アイツが黙ってるわけない。

IE11問題

IE11はSVGの表示はできるけど、use要素の表示には対応してないらしいです。svg4everybodyという便利なjsを用意してくれている英雄がいたので使わせて頂きました。

<script src="/path/to/svg4everybody.js"></script>
<script>svg4everybody();</script>

まさかのiOS 9.3問題

ここまで実装してなんとiOS 9.3で、アイコンを表示する度にall-icons.svgを毎回毎回サーバーまで呼び出している事がわかりました。キャッシュしてくれない。リクエスト数1回にするどころか、爆発的に増やしている。。。。。。。。調べても対応策は見当たらない。。。。うーん。。。。。。。。

パソコンに乗るシーちゃん
いくら可愛くても、そこは座っちゃダメ。

最終手段

そもそもSVGはコードなんだから、all-icons.svgの中身をhtmlに直接書いてしまおう! うちはテンプレートを使っているので書くのも一箇所でOK!これによって、htmlは長くなるけど、アイコン系の画像のリクエスト数は0になりました!しかもuseの記述も短くなった!

// before
<use xlink:href=“/path/to/all-icons.svg#logo"/>

// after
<use xlink:href=“#logo"/>

めでたし!めでたし!

結果

全ての画像(写真を除く)において

  • リクエスト数が0になりました!
  • cssで拡大縮小可能になりました!
  • cssで色指定できるようになりました!

以上、ざっくりですがSVGスプライトの実装方法でした!

眠るシーちゃん

最後に

我々みんなのマーケットテックチームでは「くらしのマーケット」を一緒に作る仲間を募集しています!どんな環境で開発しているかはこちらの記事にまとまっています。興味がある方はぜひ気軽に連絡ください (コーポレートサイト https://www.minma.jp/

次回は、オフィスにいる猫のオスとメスの区別がつかない、ディレクターのツカモトさんがスクラムについて書きます。