HTMLからはじめるWebパフォーマンス

#WebパフォーマンスにおいてHTMLで出来ること

Webパフォーマンス Advent Calendar 2017 9日目の記事です。
比較的取り組みやすいHTMLの変更だけで、Webパフォーマンスを改善する方法を紹介します。
ここではHTMLの圧縮等は扱いません。


##Resource Hints(dns-prefetch, preconnect, prefetch, prerender)

指定しておくことで、ページ遷移時に名前解決・接続・リソースの取得・レンダリングを早めることができる。
Resource Hintsはあくまでページ遷移時に効果を発揮するものなので、初回読み込みするページでは関係がない。

https://developer.mozilla.org/ja/docs/Web/HTML/Link_types
https://www.w3.org/TR/resource-hints/

以下のサイトでかなり詳しく解説されていますので
それぞれの説明は省略します。

resouce hintsとpreloadを使ってリソースの取得を最適化する | 69log
https://blog.kazu69.net/2016/03/19/optimize_resources_using_resoucehint_and_preload/

Resource Hints API でリソースの投機的取得 | blog.jxck.io
https://blog.jxck.io/entries/2016-02-11/resource-hints.html



ブラウザの対応状況は以下を確認してください。

Can I use... Support tables for HTML5, CSS3, etc
https://caniuse.com/#search=Resource%20Hints

``preconnect``についてはSafari Technology Previewに既に実装されているので、
近いうちSafari/mobile Safariにも実装されるはず。

Safari Technology Preview 42
https://webkit.org/blog/8001/release-notes-for-safari-technology-preview-42/


##Preload

該当ページで使用するリソースを先読みすることができる。
リソース取得によるブロッキングを防ぐので、パフォーマンスが向上する。
https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content

リソースの先読みと言えば、Chromeに実装されていた[subresource](https://www.chromium.org/spdy/link-headers-and-server-hint)があるが、こちらには優先順位を決める方法がなかった。
Preloadは``as``で優先順位の指定が可能。

```html:HTML
<link rel="preload" href="/fonts/webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">
```

ブラウザの対応状況はChrome 50,Safari 11,Android 56,Firefoxは後述。

>[1] This feature was available in Firefox 56, but only for cacheable resources. It has been disabled in Firefox 57 because of various web compatibility issues (e.g. bug 1405761). An improved version that works for non-cacheable resources is expected to land in Firefox 59.

上記はMDNからの抜粋ですが、Firefoxは56の時点でキャッシュ可能なリソースのpreloadに対応していたが、57から無効になっている。（Firefox Quantumになった影響？）Firefox 59でキャッシュ不可能なリソースにも対応される予定。

例外なくIEには対応していないが、対応していないブラウザでは無視されるだけで影響はないと思われるので、
とりあえず入れておいて損はなさそう。


##``async``,``defer``

https://developer.mozilla.org/ja/docs/Web/HTML/Element/Script

リソース取得中にHTML Parserをブロックすることがなくなる。
外部ファイルを指定した場合のみ指定可能で、インラインに指定することはできない。
``async``,``defer``を指定した場合、``document.write()``を使用することはできない。


###async
非同期で実行する。

```html:HTML
<script src="/js/javascript.js" async></script>
```

###defer
パース完了後、DOMContentLoadedが発生する前に実行する。

```html:HTML
<script src="/js/javascript.js" defer></script>
```


``async``,``defer``を付与する場合でも、``<head>``側で指定するか``</body>``側で指定するかによって速度が変化する。
（リソース取得以外にも実行時のブロックがあるため）
以下のサイトで詳しく検証されています。

TOP - スクリプト配置とページ速度
http://contentloaded.com/ja/dom-ready/


##番外編（HTML5でよく見かける不要な記述色々）

なるべく不要な記述は書かないようにしましょう。

###``link``,``script``タグ


####NG

```html:HTML
<link type="text/css" rel="stylesheet" href="/css/css.css">

<script type="text/javascript" src="/js/javascript.js"></script>
```

HTML5ではtype属性は不要。

####OK

```html:HTML
<link rel="stylesheet" href="/css/css.css">

<script src="/js/javascript.js"></script>
```


###名前空間指定(Facebook)

####NG

```html:HTML
<head prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#">
```

何故かHTML5とXHTML1.0の名前空間の書き方が混在している。
HTML5では名前空間をprefix属性で指定するので、xmlns属性は必要ない。
SVGをHTMLに埋め込む際も不要。

####OK

```html:HTML
<head prefix="og: http://ogp.me/ns#">
```
※fb/websiteなどは省略。