Webページを高速化するには

# はじめに
`HTMLコーダー&ウェブ担当者のためのWebページ高速化超入門本`を読んだのでまとめてみました。詳しくはそちらを参照してください、分かりやすかったです。

# 目標
データの転送を最適化し、Webページの初期表示を高速化する

# 参考
[HTMLコーダー&ウェブ担当者のためのWebページ高速化超入門](https://www.amazon.co.jp/HTML%E3%82%B3%E3%83%BC%E3%83%80%E3%83%BC-%E3%82%A6%E3%82%A7%E3%83%96%E6%8B%85%E5%BD%93%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEWeb%E3%83%9A%E3%83%BC%E3%82%B8%E9%AB%98%E9%80%9F%E5%8C%96%E8%B6%85%E5%85%A5%E9%96%80-%E4%BD%90%E8%97%A4-%E3%81%82%E3%82%86%E3%81%BF/dp/4297105802/ref=sr_1_56_sspa?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=web%E3%82%B5%E3%82%A4%E3%83%88+%E9%AB%98%E9%80%9F&qid=1562118277&s=gateway&sr=8-56-spons&psc=1)
[【電子書籍】Chromeデベロッパーツールを使いこなそう Network編](https://booth.pm/ja/items/1310814)
https://www.seohacks.net/basic/terms/mfi/
https://ferret-plus.com/8056

## Webサイト測定ツール
* モバイルページの読み込み速度解析サイト(TEST MY SITE)
  - https://www.thinkwithgoogle.com/intl/ja-jp/feature/testmysite
  - モバイルページのみ
* webページの速度判定(PageSpeedInsights)
  - https://developers.google.com/speed/pagespeed/insights/?hl=ja
  - PC、モバイルの両方診断OK
  
上記２つは診断内容が少し異なるみたいです
違いについて↓
https://ferret-plus.com/8056

## 昨今のインターネットの利用環境
* スマホの利用者は`85%`
* Googleの2017年の調査でモバイルサイトのページ読み込みに`3秒以上かかる場合、53％のユーザが離脱`
* MFIとは「Mobile First Index（モバイルファーストインデックス）」の略称で、インデキシングの対象をPC向けのページから、モバイル向けのページに変。さらに`採点要素にWEbサイトが表示されるスピード`が追加

## 大まかなボトルネックの場所
* 通信環境
* サーバー側(webサーバなど)
* アプリケーション(コンテンツの内容)
  - 重い画像
  - 重い動画
  - 動的に生成など
* クライアント側(PC)

## フロントの高速化とは
フロントエンドはもっともWebサイトの高速化に着手しやすい領域

# 簡単なChrome DevToolsの使い方
* networkタブで`disable cache`にチェック
  - ページの情報をキャッシュしない

* 一番下のステータスバー
![cromeinfo.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273424/e57b025a-53f3-da7b-5cd4-874790c90ed3.png)



### ステータスバーの各項目

* Finish: 
  - ページが表示されるまでかかった時間
* DOMContentLoaded: 
  - HTMLの読み込みと解析が終わった時間(CSS、画像含まない)
* Load:
  - ページを完全に読み込み終わった時間
* requests:
  - サーバーからダウンロードしたファイルの数
* transferred:
  - サーバーからダウンロードしたファイルの総容量。`数十MB～数百MB`だと時間がかかる。

### waterfall
ChromDevToolのURLが書かれている行のWaterfall列

![mttf.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273424/1bd79fbf-db4a-9345-fb48-1baf0cf89837.png)

* Queued at:
  - ネットワークパネルで計測が始まった時間
* Started at:
  - キューイングの終わった時間
* Queuing: 
  - Waterfall所の白いライン。Queued at + Queueing = Started at
* ResourceScheduling:
  - リソース取得のキューイングを表示
* Connection Start:
  - サーバーとの接続状況を表示
* Stalled: リクエストを送信できるようになるまでの待機時間
  - InitialConnection: TCPハンドシェイクやSSLを含んだ初期接続を確立するまでの時間
* SSL:
  - SSLのハンドシェイクに要した時間

* Request/Response
  - 実際にデータのやりとりの状況を扶養時
* Request sent: 
  - リクエストの送信にかかった時間
* Waiting(TTFB):
  - 最初の１バイト目を受け取るまでにかかった時間。`推奨時間:200ミリ秒`。これを超えると`サーバーが遅いか回線`が遅いかに着目する。
* ContentDownlad:
  - レスポンスのデータを受信するのにかかった時間

[項目について詳細](:https://developers.google.com/web/tools/chrome-devtools/network/reference#timing-explanation)

# webページの画像の最適化
* 一番カンタンに削除効果が期待できる
* 画像の特徴にあう形式を選び、適切な大きさに縮小し、圧縮する
  - 画像の容量を減らすことが目的

### 適切な画像選択
* jpeg
  - 写真ななど素材の色が多い画像に適している
* PNG
  - イラストやロゴなど色が少ない画像に適している
* GIF
  - パラパラアニメーション
* SVG
  - 新しい形式。ロゴや簡単な図形

### 画像を縮小して圧縮する
* 画像編集ソフトで縦横の幅を小さく縮小
  - そもそも適正な大きさかの確認はChrome Devtoolで`もとの大きさ`と`実際に表示されている大きさ`が確認できる。これに違いがあれば縮小したほうがよさそう
  - Photoshopやwindowsのペイントで縮小できる
* 人には感じにくい色の情報を省く
  - Antelope
  - ImageOptimなど

### 画像のLazyload
* サイト表示した際に表示されていない画像は読み込まず、スクロール範囲内に近づいてからダウンロードして表示させる
* 縦に長いページで画像を多用しているようなサイトに有効
* JavaScriptのプラグインで対応することが多いみたい

# テキストファイルの圧縮
### 圧縮など
* JavaScriptやCSSをまとめたりするのはWebアプリケーション側で自動でやってくれるので割愛

### サーバー側
しかし、サーバ側でHTTP2という通信方式が進化したため、複数ファイルを一つにまとめるというテクニックは過去のものになりつつある

#### HTTP1
* 上記のChromeDevToolの画像のRequestsでもわかるように、トップページを表示するだけでも多数のTCP接続が走る　→　サーバーの負荷、時間がかかる


#### HTTP2
* 1つのTCP接続を用いて複数のリクエスト/レスポンスのやり取りできる
 - 3ウェイハンドシェイクが一度だけ　→ サーバーの負荷、時間の軽減
* httpsのみでしか通信できない

詳しいHTTP2のメリット↓
https://qiita.com/uutarou10/items/7698ee3336c70a482843

# 体感的な表示速度の向上(ファーストビュー＆Above the fold)
* 最初に見える領域をその下の領域よりも優先して表示させるテクニック
* PCのファーストビュー目安
  - 1920×1080
* スマホのファーストビュー目安
  - 375×667

### ファーストビュー関連のJavaScriptの最適化
ブラウザがページをレンダリングし始めるのはJavaScriptファイルをすべてダウンロードして解析し終わったあと。そこでJavaScriptの解析が終わるのを待つことなくHTMLのレンダリングをさせることができるようにするために`defer属性やasyncを利用する`

ファストビュー関連のJavaScriptダウンロードを待つことなくファストビューを表示できるようになる

<script src="js" deferやasync>

基本deferを使用してasyncは順不同でjavascriptを読み込むので、他のJavaScriptファイルに依存せず、`ファーストビュー付近に関連するJavaScriptであればasyncを使う`

### CSSの最適化
CSSファイルをダウンロードが全て完了してから解析してブラウザはレンダリングを始める

#### CSSの非同期
* レンダリングをブロックせずにCSSを読み込むことができる
* すべてのCSSの読み込みを非同期にしてしまうとページ表示のときにバラバラにCSS適用がされて見栄えが悪くなる=FOUC(Flash of Unstyled Content)
* そこでまずファーストビューのCSSだけをheadタグに直接書き込む。これでファーストビューをうまく表示できるようにする。`ファストビューより下の領域のCSSを非同期に読み込む`
  - 抽出方法 https://jonassebastianohlsson.com/criticalpathcssgenerator/
    + 自動で抽出してくれる
* その他のCSSにかんしてはpreloadとas=styleを使用して非同期にする
 
<link rel="preload" href="css/styles.min.css" as="style">

### 測定方法
Chrome DevTools の`Audits`を使うと`体感的な表示速度`がわかるようになる。

# キャッシュの有効活用と不要なコンテンツの排除
* サーバー側(.htaccessなど)で画像やcssなどのブラウザキャッシュ期間を設定できる
* もう一度サイトを見直してファーストビューに重い処理はないか、むやみに画像を使ってないかなど調べて不要なものは取り除く



# まとめ
Chrome DevToolsのWaiting(TTFB)項目(最初の１バイト目を受け取るまでにかかった時間)をみて`200ミリ秒を超えるよう`だとサーバーチェック、`200ミリ秒以内`であればフロント側チェックして上記項目を試してみる価値あり