週刊SVG

SVGの最新ニュースや制作のコツなどの情報を毎週お知らせします

仕様から考えるSVGファイル最適化について

#Tips #FAQ

Adobe Illustrator CC 2015.3で「別名で保存」からSVGファイルを書き出すとこのようになります。

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 210 210" enable-background="new 0 0 210 210" xml:space="preserve">
<rect fill="#42479B" width="210" height="210"/>
<polygon fill="#FFA500" points="106.2,12.5 135.7,72.2 201.6,81.8 153.9,128.3 165.2,194 106.2,163 47.2,194 58.5,128.3 10.8,81.8 
	76.7,72.2 "/>
</svg>

このままだと不要な記述や省略できる部分が多くあります。

例えば最適化ツールのSVGOを適用すると、

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 210">
  <path fill="#42479B" d="M0 0h210v210H0z"/>
  <path fill="#FFA500" d="M106.2 12.5l29.5 59.7 65.9 9.6-47.7 46.5 11.3 65.7-59-31-59 31 11.3-65.7-47.7-46.5 65.9-9.6z"/>
</svg>

(※見やすいようにここでは改行とインデントを追加)

かなりすっきりしました。

このように、オーサリングツールから出力されたSVGファイルには省略できる記述が多く、SVGOやScourなどを用いてそれらを削ることでファイルサイズの軽量化を行えます。

しかし一方でツール任せにしてしまうと、どういった根拠があってその記述を削除しているのか?最適化による弊害は無いのか?といった点は気がかりではあります。

そこでこの記事ではSVGの様々な要素について解説していき、なぜ削除できるのか?仕様の面での裏付けや、またその場合の注意点などを挙げていきます。

簡易目次

はじめに

SVGはXMLを基盤にした2次元グラフィックス記述言語です。

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 210 210" enable-background="new 0 0 210 210" xml:space="preserve">
<rect fill="#42479B" width="210" height="210"/>
<polygon fill="#FFA500" points="106.2,12.5 135.7,72.2 201.6,81.8 153.9,128.3 165.2,194 106.2,163 47.2,194 58.5,128.3 10.8,81.8 
	76.7,72.2 "/>
</svg>

それを踏まえてIllustratorから出力されたSVGファイルを見ると2つの部分に分けられます。

  • XML宣言
  • ルート要素

ここではこの基本構造と各属性などについて解説していきます。SVGには他にもrect要素やpath要素などの図形に関する要素もありますが、今回はそれらは扱いません。

また特に記載の無い場合、基になる仕様はSVG 1.1 Second Editionとしますが、次期バージョンとして現在策定中のSVG 2ではどのように変わり、将来的にはどうなる予定なのか?といった補足を行う項目もあります。

XML宣言

SVG文書はXML文書でもあるので、始めにXML宣言を記述することが推奨されます。

<?xml version="1.0" encoding="utf-8"?>

ですが、XML宣言はこれらの条件を満たしていれば省略が可能です。

  • XMLのversionが1.0である
  • スタンドアロン文書宣言がnoである
  • 文字コードがUTF-8またはUTF-16である、もしくはContent-Typeヘッダなどに文字コードの情報がある

一つ目のversionはそのまま1.0ですから問題ありません。

スタンドアロン文書宣言はyesまたはnoの値を持ち、仮にyesであればこのように記述されます。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

しかし、Illustratorから出力されたSVGファイルにはそもそも記述自体がありません、このようにスタンドアロン文書宣言を省略した場合はnoと見なされます。

そのため二つ目の条件も満たしています。

続いて文字コードについて。

Adobe Illustrator CC 2015.3でのSVGファイル保存のダイアログ画面、文字コードの設定がUTF-8になっている

Illustratorの初期設定では文字コード設定はUTF-8であるため、特に変更していない限りは条件を満たします。またレスポンスヘッダのContent-TypeでこのようにMIMEタイプと一緒に文字コードを提示できます。

Content-TypeヘッダでMIMEタイプと文字コードを提示した様子
(Chromeの開発ツールでこのページのSVGファイルのレスポンスヘッダを検証した結果)

コメント

<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

XMLはHTMLと同じく<!---->で囲んだ部分がコメントとなります。

Illustrator以外の他のオーサリングツールでものソフトウェア・アプリの名前やバージョンなどをコメントで記述して出力することが多いです。しかし、利用者にとってはこうした情報が直接なにかの役に立つわけではありませんから、削除してファイルサイズを軽量化した方が良いでしょう。

文書型宣言

最新版のAdobe Illustratorでは記述しなくなりましたが、Illustrator CC以前では文書型宣言をSVGファイルに記載していました。今回はせっかくなので、こちらも解説します。

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

文書型宣言はSVG 1.1 SEでは非推奨になっており削除するのが望ましいです。

この仕様では DTD が与えられているが、 XML 文書の妥当性検証には問題がある事も知られている。 特に、 DTD では名前空間をスマートに扱えない。 SVG 文書に DOCTYPE 宣言を含める事は、推奨されない

概要 – SVG 1.1 (第2版)

古いSVGファイルなどで文書型宣言が記述されたものがあれば削除しておいた方が良いでしょう。

ルート要素

続いてルート要素である、最も外側のSVG要素の各属性について解説していきます。

<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
	 y="0px" viewBox="0 0 210 210" enable-background="new 0 0 210 210" xml:space="preserve">

SVG名前空間宣言

<svg xmlns="http://www.w3.org/2000/svg">

SVG名前空間宣言はSVGファイルには必ず記述しなければなりません。

いかなる場合でも、すべての SVG 要素が SVG 名前空間に属するものと識別されるようにするためには, XML 名前空間 勧告 [XML-NS] に従って SVG 名前空間宣言が与えられなければならない。

文書構造 - SVG 1.1 (第2版)
古いSVGファイルでは名前空間宣言が無いことも

SVG 1.0の仕様がW3Cから勧告されたのは2001年9月、実は勧告案の段階ではSVG名前空間宣言の省略が可能でした。そのため勧告前の2000年6月にリリースされたIE用プラグインのAdobe SVG Viewerでは、名前空間宣言が無くてもSVGを表示できました。

そのこともあってか、当時のAdobeのページではSVG名前空間宣言の無いSVG文書がサンプルとして掲載されています。古いSVGの書籍や、当時のウェブサイトではこうしたSVG名前空間宣言の無いSVG文書の作例が残っていることもありますが、現在の仕様では適切に表示できないので留意してください。

HTML5のSVG要素では名前空間宣言が省略できる

なお、SVGファイルではなくHTML5のSVG要素として扱う場合にはSVG名前空間宣言は省略できます。

HTML5のSVG要素では名前空間宣言が省略できる

XLink名前空間宣言

HTMLではリンクを張る際には

<a href="http://example.com/">リンクテキスト</a>

a要素にhref属性で記述します。

一方でSVG文書ではXLink名前空間のhref属性を使います。

<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <a xlink:href="http://example.com/">
    <path fill="#42479B" d="M0 0h210v210H0z"/>
  </a>
</svg>

Illustratorから出力されるSVGファイルも含め、多くの場合はXLink名前空間と共に接頭辞が宣言されxlink:href属性として使われます。

xlink:href属性はa要素やimage要素、use要素など様々な要素で使われ、それらの要素でリンク機能を利用するのであればXLink名前空間宣言は必ずしなければなりません。

ただし、a要素やimage要素、use要素などのリンクを行う要素がSVG文書に含まれないのであれば、XLink名前空間宣言は省略できます。具体的には冒頭の例ではpath要素のみであるため、XLink名前空間宣言が省かれています。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 210">
  <path fill="#42479B" d="M0 0h210v210H0z"/>
  <path fill="#FFA500" d="M106.2 12.5l29.5 59.7 65.9 9.6-47.7 46.5 11.3 65.7-59-31-59 31 11.3-65.7-47.7-46.5 65.9-9.6z"/>
</svg>
SVG 2ではXLink名前空間宣言が省略できる予定

現在策定中のSVG 2ではXLink名前空間宣言及び接頭辞は省略できるようになる予定です。

xlink:href 属性は、名前空間なしの href の利用の支持を受けて,廃止予定にされた。

リンク - SVG 1.1 からの変更点 — SVG 2

つまり従来のSVG 1.1 SEの仕様ではこのように

<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 210 210">
  <defs>
    <path id="star" fill="#FFA500" d="M106.2 12.5l29.5 59.7 65.9 9.6-47.7 46.5 11.3 65.7-59-31-59 31 11.3-65.7-47.7-46.5 65.9-9.6z"/>
  </defs>
  <use xlink:href="#star"/>
</svg>

use要素などでは、XLink名前空間宣言を行いxlink:href属性を使う必要がありました。

しかし、SVG 2では

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 210">
  <defs>
    <path id="star" fill="#FFA500" d="M106.2 12.5l29.5 59.7 65.9 9.6-47.7 46.5 11.3 65.7-59-31-59 31 11.3-65.7-47.7-46.5 65.9-9.6z"/>
  </defs>
  <use href="#star"/>
</svg>

このようにXLink名前空間宣言をせずともhref属性だけで済むようになる予定です。

ただ将来的な話はさておき、href属性の現在の実装状況はどうか?というと芳しくありません。

SVG 2のhref属性の対応状況
xlink:href属性href属性

対応している環境

  • IE11(IE10以下は未検証)
  • MS Edge
  • Chrome / Opera

未対応な環境

  • Firefox
  • Safari

またAdobe Illustrator、Inkscapeといったオーサリングツールでも未対応です。そもそも策定途中の仕様であるため仕方ないのですが、現段階ではXLink名前空間宣言の省略は行わない方が良いでしょう。

viewBox属性

冒頭で挙げたSVGOでの最適化の例でもある通り、

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 210">
  <path fill="#42479B" d="M0 0h210v210H0z"/>
  <path fill="#FFA500" d="M106.2 12.5l29.5 59.7 65.9 9.6-47.7 46.5 11.3 65.7-59-31-59 31 11.3-65.7-47.7-46.5 65.9-9.6z"/>
</svg>

viewBox属性が残っていることからSVG文書には必須の属性であると誤解されがちですが仕様上は省略が可能です。

ただし、viewBox属性を省略した場合は挙動が複雑になりがちで、扱いが難しくSVG上級者向けの手法です。特に理由がない限りは原則viewBox属性を記述した方が使いやすいです。

version属性

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">

Illustratorでの初期設定ではversion属性はSVG 1.1 SEを示す1.1で書き出されます。

策定中のSVG 2では削除が予定されています。

svg 要素から baseProfile, version 属性が削除された。

文書構造 - SVG 1.1 からの変更点 — SVG 2

x属性、y属性

<svg x="0px" y="0px" xmlns="http://www.w3.org/2000/svg">

x属性、y属性は記述が無い場合はそれぞれ0と見なされるので、こうした場合には省略が可能です。そしてさらに言えば

( 最も外側の svg 要素 に対しては、どんな意味も効果も生じない。)

文書構造 – SVG 1.1 (第2版)

と定義されており、ルート要素(最も外側のsvg要素)では仮にx="0"でもx="300"であっても記述する意味が無いので省略した方が良いでしょう。

enable-background属性

<svg xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 210 210"
  enable-background="new 0 0 210 210">

enable-background属性については詳しくは別の記事でまとめています。

enable-background属性の意味と省略できる理由について

内容を一行で簡潔にまとめると

enable-background属性が実装された環境は現状ほぼ無く、記述してもしなくても同じなので省略すべき

となります。

xml:space属性

<svg xmlns="http://www.w3.org/2000/svg"
  xml:space="preserve">

xml:space属性は省略によって挙動を変えるため、記述に手を加えるべきかは状況によります。

xml:space属性はdefault(初期/既定値)とpreserveの2種類の値をとり、文字列における空白の処理を指定します。それぞれの指定の共通する部分、また違う部分をまとめると

defaultpreserveどちらも共通の扱い
  • 全てのタブ文字をスペース文字に置き換える。
defaultでの扱い
  • 全ての改行を取り除く
  • 先頭及び、末尾の連続するスペース文字を取り去る
  • 連続するスペース文字は1個にまとめられる
preserveでの扱い
  • 全ての改行はスペース文字に置き換えられる

となります。

xml:space属性でdefaultpreserveの比較

具体的にはこのような指定にした場合

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 60">
<text xml:space="default" y="20">
   Scalable
   Vector
   Graphics
</text>

<text xml:space="preserve" y="40">
   Scalable
   Vector
   Graphics
</text>
</svg>
xml:space属性による空白の扱いの違いを示したSVGファイル

文章の表示にこうした違いが現れます。

SVGの仕様において、xml:space属性の影響が現れるのは概ねtext要素です。

その場合に安易にxml:space属性を削除してしまった場合には規定値であるdefaultと見なされ、意図とは違うずれが生じる可能性があります。SVGOには珍しく、最適化によって挙動が変わる処理なので該当する要素がある際には注意が必要です。

ただ、そもそも文字の配置にスペース文字やタブ文字、改行で調整するのは避けるべきですが……。

参考リンク