ど素人でもできた、SpeedCurveでWebサイト速度計測&高速化

## WHO こんな人は高速化できるかも
- フロントエンドの速度を全く気にせず書いている
- 画像の遅延読み込み？やってない
  - 600x600くらいの画像がページに20個ほどある
- なんとなくjsはheadに書いている
- なんとなくfont awesomeを使っている


## WHAT 何をやったのか
- 個人開発の[Webサービス](https://hufurima.com/)を高速化した
- [SpeedCurve](https://speedcurve.com)を使ってページ読み込みの速度を計測
- 計測結果から、取得に時間がかかっているリソースを探す
- そのリソースに注目して、特にページの表示が始まるまでの（真っ白な）時間を短縮


## WHY なぜ高速化？
- 遅いと離脱率が高くなるから
- 色々データがあるみたいですが、とりあえず速くなればOKという考え


## 手順
では早速やっていきましょう


## 1. Speed Curveへの登録
まずは、Speed Curveの無料枠に登録しましょう。Speed CurveはWebサイト速度計測ツールです。クレカなしで登録できて、30日間無料です。この登録が簡単で、URLを入れて、メールアドレスとパスワードを入れるだけで登録できます。

https://speedcurve.com/setup/trial/

<img width="1245" alt="speedcurve1.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/41a5c44a-9cda-815c-2207-c888a7776667.png">


## 2. 計測
左のメニューから、settingsを選択します

<img width="1214" alt="スクリーンショット 2018-11-28 18.49.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/0946ff00-f7d2-aa8c-2f8c-c23e50a9a000.png">

Sites > + ADD SITE をクリックして、計測したいサイトを追加するページにとびます。
すると以下のページに飛ぶので、ここで計測したいサイトを追加します

<img width="1232" alt="スクリーンショット 2018-11-28 18.53.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/e7ef58cc-f243-dfa6-76e7-cfb6a9b01f88.png">

ハンバーガーメニューのdeployから、計測します。

<img width="1226" alt="スクリーンショット 2018-11-28 18.47.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/8b98b492-0ca1-a636-23c2-09894797a349.png">

下図の右上の「TEST NOW」を押します

<img width="1224" alt="スクリーンショット 2018-11-28 18.47.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/65a1fd8f-55a4-e9c3-f8da-fd2fdc4da608.png">

すると、テストするサイトやラベル（テストの名前）を入力するフォームがでてくるので、入力して、「Kick off test now!」を押してテストを開始しましょう。

<img width="1229" alt="スクリーンショット 2018-11-28 18.49.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/6416d1e4-b822-1cd4-63af-43ff2e6039b9.png">

<img width="1208" alt="スクリーンショット 2018-11-28 18.49.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/10281537-caf6-133c-7ad7-5d4af9b73485.png">

こんな感じで結果が出ます。何度かテストをすると、前の結果（直前ではない）との比較（x% faster など）がでます。

<img width="1201" alt="スクリーンショット 2018-11-28 18.55.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/caaf31b4-1dad-7bf8-c6eb-3697745dab08.png">


で、どこをみたらいいの？という話ですが、左のサイドバーにある「improve」を選択しましょう。

<img width="1199" alt="スクリーンショット 2018-11-28 18.56.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/8f41b646-1ca7-6b8d-1d0e-066d886cd8d1.png">

「improve」の「performance」をみてみましょう。

<img width="1226" alt="スクリーンショット 2018-11-28 18.58.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/23e3c811-ff0a-c5b8-4aca-18b476bf7aad.png">

「Eliminate render-bloking resources」を見てみましょう。
このリンクをクリックすると、

「Browser waterfall」という項目が出てきます。

<img width="1205" alt="スクリーンショット 2018-11-28 19.02.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/1b4ebaef-26e4-cb27-012e-60f586188c80.png">

これは、サイトが表示されるまでに

- どのファイルが
- どのタイミングで（どの順番で）
- どれくらいの時間で

読み込まれるかがわかるので、それぞれ以下のことがわかります

- どのファイルが: どのファイルがボトルネック（速度低下の主な原因になるもの）になっているか
- どのタイミングで、: 特に、ページの表示が始まるよりも先に読み込まれているかを見ましょう
- どれくらいの時間で: 時間がかかっている＝ボトルネックになっているということです


## 2. 改善する
それでは、改善しましょう。先ほどの「Browser waterfall」をみます

<img width="1213" alt="スクリーンショット 2018-11-28 19.19.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/82d0d2bf-96eb-e7e2-222c-24a57e47de06.png">

縦に伸びている線が時系列で重要なポイントを表しています。
実際に、DOM Content Loadedあたりに縦の線が集中していますが、**ここがちょうどページが表示され始める部分です。**ここまでくると、ユーザにとっては「もうすぐ表示されるな」と思わせることができます。

ここまで来てしまえば、ユーザからはページが見えてきてストレスがなくなってくるので、とりあえずここより後ろは無視します。

逆に**ここに行き着くまでの速度が非常に重要になってくる**と考えています。

というわけで、まずはこの**「DOM Content Loaded」あたりより前に読み込まれるファイルが少なくなるように**改善していきます。

ここのゾーンで読み込まれるファイルには、だいたい以下のようなものがあります。

- cssファイル
- html（imgなどがある場合、画像などを含む）
- 同期的に読み込むjsファイル

### cssファイル
基本的に、cssはページの表示が始まった時には適用された状態である必要があります。なので、表示したいページに必要なCSSファイルは先に読み込んでおく必要があります。これは仕方ありません。


### html（imgなどがある場合、画像などを含む）
imgタグを含んでいる場合、普通にimgタグを使う場合は**ページの表示前に画像を読み込んでしまいます。これはかなり速度の低下につながります。**

非同期に読み込むようにすることで、 **ページを表示しながら画像を読み込んでくれるようになるので、ページの表示開始までの速度が大幅に改善できます。**


### jsファイル
ページの初期表示に必要のないjsファイル（レイアウトなどに問題を与えないものなど）は、非同期に読み込むことで、ページの表示開始を速くすることができます。


### 速度を上げる方法
- 非同期で読み込む
- 不要なファイルを削る
  - ファイル数を減らす
  - ファイルのサイズを小さくする


## 今回やったこと


### 1. 画像を非同期読み込みにする
今回は、lazysizesというライブラリを使いました。
https://github.com/aFarkas/lazysizes

導入が簡単で、以下をlazysizes.min.jsとして保存して読み込むだけで使うことができます。

http://afarkas.github.io/lazysizes/lazysizes.min.js


```html
<body>
  <!-- 略 -->
  <script src="lazysizes.min.js" async=""></script>
</body>
```

imgタグの書き方を以下のようにちょっと変えるだけで、非同期読み込みが行われます。

```html
<img data-src="image.jpg" class="lazyload" />
```

これだけで割とスコアが上がるので、ぜひ試してみましょう！
ただ、全ての画像を非同期にしてしまうと、最初にaltの文字が出てしまったり、ちょっとユーザを心配させる挙動になるかもしれないので、リスト表示などの画像や、画面の下の方にあるスクロールしないと見えない画像を非同期にするとよいでしょう。

（この時点でぜひ一度計測をし直してみましょう）

## 2. 不要なファイル・重複ファイルの削除

### サイズの大きいファイルの見つけ方
<img width="1207" alt="スクリーンショット 2018-11-29 9.37.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/82966246-d036-8802-f90e-96f89b9f2a0d.png">

先ほどの「Browser waterfall」をみると、横方向に緑やオレンジ色のバーが並んでいると思います。これが**長いものは、読み込みに大きな時間がかかっています。**基本的には、この長くなっているものがサイズの大きいファイルであったり、遅いcdnで読み込んでいたりという感じになります。

僕の場合は、cdnで使っていたfont awesomeが結構大きいファイルになっていました。（この図は改善後ですが）


### font awesomeの一部のアイコンだけを使う
ここでは、font awesomeの一部のアイコンだけを使うことでファイルサイズを減らす方法をご紹介します。
といっても、以下のサイトが詳しかったので、これの通りにやればOKです。笑

IcoMoonを使ってFont Awesomeのアイコンを必要なものだけ使う方法
http://www.nowhere.co.jp/blog/archives/20170321-191521.html

これで生成されたzipの中にある、fontsフォルダとstyle.cssを同じディレクトリに配置して、htmlファイルでstyle.cssを読み込めば、font awesomeと同じ使い方ができるので簡単です。（`<link>`タグだけを書き換えればOK）




## 3. jsの読み込み

### 非同期で読み込む
https://developers.google.com/speed/docs/insights/BlockingJS?hl=ja によると、以下のようにasync属性をつけるとページの表示を妨げないので、表示速度が速くなります。

```html
<script async src="my.js">
```

また、defer属性を使うと、jqueryなどの先に読み込みたいものは先に読み込みつつ、ページの表示を妨げないようになるようです。

```html
<script type='text/javascript' src='/js/jquery.min.js' defer></script>
<script type='text/javascript' src='/js/bootstrap.min.js' defer></script>
<script type='text/javascript' src='/js/script.js' defer></script>
```

### 読み込み位置を適切にする
恥ずかしい話ですが、jsの読み込みは適当な場所でやっていました。

jsの読み込みは、基本的に閉じタグ `</body>` の直前に書くのが一般的らしいです。
ブラウザはファイルの上から解釈するので、容量の大きいjsをファイルの上の方で読み込んでしまうと、その後の処理が遅くなってしまうので、閉じタグ `</body>` の直前に書くとよいらしいです。

http://www.atmarkit.co.jp/fwcr/design/benkyo/htmltuning02/02.html

（しかしこれに関しては、それほど効果は高くないという話もあります。）


## 結果
だいたい上記のことを試した結果、以下のように改善されました！（apple iphone7）

<img width="1201" alt="スクリーンショット 2018-11-28 18.55.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/caaf31b4-1dad-7bf8-c6eb-3697745dab08.png">

ちなみに一番効いたのは、「画像の遅延読み込み」でした。
また、計測値に多少誤差がある感じなので、異常値が出たらもう一回やってみるのもよいかもしれません。


## まとめ
- 個人開発の[Webサービス](https://hufurima.com/)を高速化した
- [SpeedCurve](https://speedcurve.com)を使ってページ読み込みの速度を計測した
- ページの表示が始まる前の速度を改善できた
  - 特にlazysizesを使った画像の遅延読み込みが


## 参考
- https://helog.jp/javascript/async-defer/
- https://developers.google.com/speed/docs/insights/BlockingJS?hl=ja