Optimise HTML - High Performance Web 2015

# HTML の最適化

ここでいう最適化は、平たく言えば minify だ。
JS や CSS は割とカジュアルに圧縮するのに HTML を圧縮するという手法は、そこまで浸透していないように思われる。

技術的に言えば、 HTML の自由度が高すぎて正確にパースするのは難しいとかもあるかもしれない。
運用的に言えば、そこまでバイト数に対して敏感じゃないというのもあるかもしれない。
なんとなく表示が壊れそうで怖いというのもあるかもしれない。

結局のところ、流行ってはいないように思う。

一番手軽な方法として、 PageSpeed を使えば、サーバの設定だけで圧縮が可能になる。
これは、アプリに手を入れないですむ。

https://developers.google.com/speed/pagespeed/service/OptimizeHtml#RemoveComments


あらかじめやるなら以下のようなツールもある。


https://kangax.github.io/html-minifier/


しかし、例えばテンプレートエンジンから HTML を吐く場合は、オプションを付けて最適化したものを吐くって言うのも不可能では無いと思われる。

ちなみに HAML では、こうした最適化が 2009 年から TODO に入ってるが、入ったままで進捗はないようだ。最初から想定して作られたものでないと難しいのかもしれない。

https://github.com/haml/haml/blob/master/TODO#L18


# 基本

ここでは HTML5 の話になるが、いろいろと削れる部分がある。

以下は、 JS/CSS とほぼ同じ。

- 要らない空白
- 要らない改行
- コメント

例えば以下なら

```html
<ul>
  <!-- the list of some example word for someone -->

  <li>fooo</li>

  <li>baar</li>

  <li>buuz</li>
</ul>
```

```html
<ul><li>fooo</li><li>baar</li><li>buuz</li></ul>
```

115 - 49 = 66 byte の削減になった。



# 閉じタグ

省略できる閉じタグが結構ある。
どうせプロダクションモードでビルドするような場合であれば、それを直接は読まないはずなので、これを消すことの問題は特にないだろう。

ルールはこの辺が詳しい。

http://qiita.com/labocho/items/54fd70c73ced35c8ba49

例えばこれだと

```html
<ul>
  <li>fooo</li>
  <li>baar</li>
  <li>buuz</li>
</ul>
```

閉じタグはいらない。

```html
<ul>
  <li>fooo
  <li>baar
  <li>buuz
</ul>
```

閉じタグの分で言うと 5 * 3 = 15 byte の節約だ。

他にも head や body の省略は全ページで効くだろうし、大きなテーブルがあるページでは数百バイト単位で減らせる可能性すらある。


# quote

意外と見ないが quote はいらない。

```html
<input type="text" name="first-name" placeholder="First name" maxlength="10">
```

こう書ける。

```html
<input type=text name=first-name placeholder="First name" maxlength=10>
```

複数値でなければ、属性数*2 で、今回は -6 byte

# URL

mixed コンテンツをさける文脈でも、もとが HTTPS の時には、外部コンテンツも HTTPS で取りたい場合がある。
具体的にはこう書く。

```
<img src="//example.com/image.jpg">
```

`http:` の 5byte が書かれているリンクから消せる。もちろんそれで問題ないものだけに限るが。


# サンプル

なんか、「すごくちまちましてるな」と思うかもしれないが、 minify はそういうものだし、 JS や CSS にしても同じこと。

問題は、ちりも積もればの部分にある。

そこで、以下のファイルを使って極限まで削ってみた。

https://github.com/ipeychev/http2rulez.com/blob/master/public/index.html

HTML として壊れていないかは、 https://validator.w3.org/ で調べている。

手順としては、

- まずこのファイル自体が invalid なので適当に直す
- 一旦 https://kangax.github.io/html-minifier/ でざっと削る
- 残っている空白を消す


# 余地

実は最後の「空白削除」ちょっと議論の余地がある。
ここで消したのは 

```html
<div>...</div> <div>...</div>
```

これをこうした。

```html
<div>...</div><div>...</div>
```

ただし、 HTML 中の空白は、複数の場合一つとしてまとめて表示される。
つまり、その空白をレイアウトとして使っている場合は、消すことで隙間がなくなって表示されるコンテンツがあるのだ。そのため、このツールは、複数スペースを一つまでに削っていると思われる。

実は、今回のテスト HTML もこの種のコンテンツだったので、厳密には見た目が変わっている。

## before

![before.png](https://qiita-image-store.s3.amazonaws.com/0/6452/4206a8af-921a-c903-669c-595cf5f5c328.png)

## after

![after.png](https://qiita-image-store.s3.amazonaws.com/0/6452/92aae357-4eed-db9c-76f7-016b7ac5e495.png)


文字間のスペースならまだしも、こうしたスタイルとしての余白は margin や paddig でやるべきなのは言うまでもない。

これは、開発の時点からそれを踏まえてやらなかったことが問題とも言える。


# 結果

こういうのを踏まえて比較した結果を貼っておく。

https://gist.github.com/Jxck/4163397b05965306bc3b

```sh
$ wc -c before.html after.html
   23819 before.html
   13901 after.html
```

23819 - 13901 = 9918 byte (58%)

よって、ざっと半分くらいまで減った。


これは、無視して良い値なのかどうかは考えてみる価値があると思う。


# link

- https://developers.google.com/speed/pagespeed/service/OptimizeHtml
- http://qiita.com/labocho/items/54fd70c73ced35c8ba49
- https://validator.w3.org/
- https://github.com/ipeychev/http2rulez.com/blob/master/public/index.html
- https://kangax.github.io/html-minifier/
- https://gist.github.com/Jxck/4163397b05965306bc3b