How to 速度改善 ー原因調査編ー

## 前提
速度改善にこれから取り組もうと思っている方向けに書きました。
すでに速度改善に取り組んでいる方からするとちょっと基礎すぎるかもしれませんが、自分の勉強メモとしてアウトプットして残そうと思った次第です。

前回の記事はこちらになります。

[How to 速度改善 ー計測・知識編ー](https://qiita.com/masanarih0ri/items/1dd54a223a0025e3b504)

ご興味ある方はどうぞ。

## 原因の調査

[前回の記事](https://qiita.com/masanarih0ri/items/1dd54a223a0025e3b504)でスコアのキャプチャを載せましたが、Page Speed Insightsの低スコアの原因については添付の画像の中に色々と書かれています。

<img width="888" alt="スクリーンショット 2019-02-28 15.29.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/76779/4ff06b15-de70-46d8-383d-6f86781f185a.png">

８個の指摘がありますので順番に見ていきましょう。

##### 1. レンダリングを妨げるリソースの除外
これはレンダリングを阻害しているファイルたちがいるよ、ということですね。
今回でいうとこんな感じで沢山のファイルがその対象となっていました。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/76779/cfe6e043-92a3-e056-cbe2-bc87527198eb.png)


ここの部分の解決策としては後ほど詳しく示しますが、指摘しているファイルたちを遅延読み込みする、必要なリソースはインラインでHTMLに書く必要がありそうです。

##### 2. オフスクリーン画像の遅延読み込み
これは、そのページのファーストビューで読み込みする必要がない画像は遅延読み込みしましょう、という指摘ですね。
見えていない所の画像については、いちいち読みこむ必要ないので、それでページの読み込み速度をあげようということです。

こんな感じで沢山指摘されていました。

![qiita2.png](https://qiita-image-store.s3.amazonaws.com/0/76779/a2495c12-3c2e-0912-4726-3e3764ce0c18.png)

これについても後ほど一つの解決策を共有します。

##### 3. 次世代フォーマットでの画像の配信
画像といえばjpeg,pngあたりがすぐに思い浮かぶと思いますが
googleさんによると
>
JPEG 2000、JPEG XR、およびWebPは、以前のJPEGおよびPNGに比べて優れた圧縮および品質特性を持つ画像フォーマットです

とのことです。
要するにその形式のものを使ってみてはどうですか？ということですね。

それぞれの画像形式についてCan I useで調べてみました。
[JPEG 2000](https://caniuse.com/#search=jpeg2000)
[JPEG XR](https://caniuse.com/#search=jpegxr)
[Web P](https://caniuse.com/#search=webp)

それぞれ対応しているブラウザが違いますね。
上記の形式でほぼ全てのブラウザに対して対応できそうですが、ユーザーエージェントを判断して出し分けたりしないといけないんでしょうか・・・。大変だ。。

##### 4. 効率的な画像フォーマット
これについては、適切な画像のファイルサイズでサーバーに格納しましょう、という感じの指摘です。
サイズが大きすぎる画像があると指摘されます。
8KBの画像でも、減らせるデータ量がまだあると指摘されています。笑
![qiita3.png](https://qiita-image-store.s3.amazonaws.com/0/76779/8960f6d8-6bca-502f-eeba-c4f4683191f3.png)


##### 5. 使用していないCSSの遅延読み込み
対象のページで使われていないCSSについてはあとで読み込むような仕組みにしましょう。ということですね。

###### critical css
critical cssとは、ページをロードするために必要とされるcssのことをさします。
一般に、ページロードは重要なCSSでのみブロックされるべき、という考えがあるので、それをまずはロードして、それ以外は遅延評価をして、あとで読み込みましょう、ということです。

##### 6. 適切なサイズの画像
これについては言わずもがな、画像のサイズを圧縮しましょうという話ですね。

##### 7. Javascriptの最適化
これも言わずもがなですが、javascriptの空白とか諸々削除して最小化してね、ということですね。
それができていないファイルがいくつかあるのか・・・。

##### 8. サーバー応答時間の短縮
これはサーバーの応答時間を改善してくださいね、という指示になります。
TTFB（Time To First Byte）はブラウザがWebサーバーにリクエストを送信してから、Webサーバーが最初の1バイトの応答をブラウザに返すまでの時間です。
無駄なクエリが走っていたり、何かのファイルの読み込みに時間がかかっていたりすると応答時間の遅延が起こる模様です。

## 原因の調査その2

page speed insightsの中身をもう少し詳しく見ていきましょう。
<img width="893" alt="スクリーンショット 2019-03-05 10.47.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/76779/137ac01b-d672-3f58-57eb-5e60452d5781.png">

##### 1. 静的なアセットと効率的なキャッシュポリシーの配信
キャッシュの有効期間を設定して、静的なアセットをキャッシュヒットさせるようにしましょう、ということですね。毎回HTTPリクエストを投げて画像を待つというのは無駄ですし。
それにしても40個以上のファイルが対象になっているようで、修正のしがいがありますねぇ・・・。

##### 2. メインスレッド処理の最小化
メインスレッド処理については下の画像にあるように、かなりJavascriptが邪魔をしているようですね。
<img width="892" alt="スクリーンショット 2019-03-05 14.02.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/76779/7b2e36ca-0aee-dd85-e66b-eb9bc75fc63e.png">

##### 3. Javascriptの実行にかかる時間の低減
Javascriptの解析、コンパイル、実行にかかる時間の短縮をしてください、という内容ですね。
こちらについては上記の「メインスレッド処理の最小化」とも密接に関係していそうです。

##### 4. 過大なDOMサイズの回避
ページに含まれるDOMノード数が1500を超えない、というのが推奨されている値のようです。
DOMノードとは、DOMツリーの中にある要素のことをさします。例えばpタグ、aタグ、imgタグなどがそれに該当します。これの個数を押さえましょうということですね。

##### ５. クリティカルなリクエストの深さの最小化
[こちらのGoogleのページ](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)によると
> クリティカル リクエスト チェーンは、クリティカル レンダリング パス（CRP）の最適化技術のコンセプトの 1 つです。 CRP を考慮してリソースに優先度を設定し、読み込む順序を指定すると、ブラウザでより早くページが読み込まれるようになります。
とのことです。まあ、要は必要なリソースだけを読み込みましょう。ということですね。

## これらの問題を解決していくための案

さて、これである程度スコアが低い理由を把握することができました。色々と指摘されていますが

大まかに
##### ①画像のサイズが適切でない
##### ②レンダリングをブロックしている要素が多数ある
##### ③キャッシュなどを設定していないのでHTTPリクエストの数が多い
##### ④ファーストビューに必要な情報以外の情報も多数読み込んでしまっている

といった問題があり、それらが原因でPage Speed Insightsのスコアが落ちてしまっていることがわかりました。

それぞれの解決策として

① [ImageOptim](https://tech.qookie.jp/posts/info-imageoptim-mac-app-free/)や[Image Compressor](https://imagecompressor.com/ja/)などで画像のサイズを適切なものにする。できればその作業を何度も行わなくても良いように、画像をアップロードしたら自動的に画像サイズを圧縮してくれるような仕組みを作る。

② Javascript、CSSについては遅延読み込みをする。
③ ブラウザキャッシュの設定をちゃんとやる。←
④ ファーストビューに対して必要な要素を割り出し、必要なものを読み込む。

といったことがあげられます。

具体的には

①

- 先ほどの[ImageOptim](https://tech.qookie.jp/posts/info-imageoptim-mac-app-free/)や[Image Compressor](https://imagecompressor.com/ja/)の利用
- Gruntなどを使い画像圧縮を自動化
- [imgix](https://www.imgix.com/)のようなCDNサービスを使って画像を配信する

②

- Javascriptについてはasync defer属性を使い非同期で読み込む
- CSSについてはpreloadを利用する

③

- 社内のプロダクトなので公開はできないのですが、どうやら対象の画像ファイルたちがキャッシュの対象になっていない模様。。対象に入るように設定する

④

- ファーストビューのに必要なCSSのインライン化、読み込む必要のないjsファイルは読み込まないようにする

といった対策をとることを検討することにしました！

次回は

How to 速度改善 ー実装編①ー を書きたいと思います。ようやく実装。。