オトナのWEBブラウザ技術入門〜WEBページの高速化についてフロントエンドでできること〜

## WEBサイトの速度とは

- ページロードの速度
    - ページが表示されるまでの速度（WEBページの読み込み速度）
- ランタイムの速度
    - ページ上での操作に対するUIの応答速度（操作感に関わる性能）

--- 

- ページロードの速度（表示までの速度） 
    - HTMLのロード
    - CSS, JS, 画像のロード
    - レンダーツリーの構築
    - 描画処理の実行

--- 

- ランタイムの速度（UIの応答速度）
    - アニメーション
    - スクロール操作
    - UIの切り替え

--- 

![IMG_1801.jpg](https://qiita-image-store.s3.amazonaws.com/0/2469/b0e250a7-9ba3-74d5-acd5-cc8fc64897e6.jpeg)

--- 

## 高速化する3つのポイント

- ネットワーク処理（HTMLドキュメントやサブリソースの取得）
- レンダリング処理（ディスプレイへの表示）
- スクリプト処理（JavaScriptによる演算やDOM操作）

---

## 速度の具体的な基準 → RAILモデル

- Response 100ミリ秒
    - UI操作の応答があるまでの時間
- Animation 10ミリ秒
    - アニメーション1フレームあたりの時間
- Idle 50ミリ秒
    - アイドル状態で行われる処理単体の時間
- Load　1,000ミリ秒
    - ページロードの時間

---

## ネットワーク処理
- ページロード速度に大きく関わる部分 
    - 指定されたURLからHTMLを取得する
    - HTMLに応じてサブリソースを取得してページを表示する
    - 
--- 

## ネットワーク処理の最適化
- データの転送量を小さくする
- データの転送回数を少なくする
- データの転送距離を短くする
 
--- 

## データの転送量を小さくする
- 配信するリソースを圧縮、最適化する
 
--- 

## データの転送回数を少なくする
- ブラウザからリクエストする回数を減らす
 
--- 

## データの転送距離を短くする
- 通信するデバイスと実際にデータをやり取りしているサーバとの物理的な距離を短くする
    - 日本国内　100ミリ秒
    - 日本⇔アメリカ西海岸 200〜300ミリ秒

---

## クリティカルレンダリングパス
- 最初のレンダリング処理が行われるまでに必要な一連の処理
    1. HTMLドキュメントのダウンロードと評価
    2. サブリソースのダウンロードと評価
    3. レンダーツリーの構築とレンダリング

---

![クリティカルレンダリングパス](http://sqlazure.jp/r/wp-content/uploads/2017/11/critical.png)

--- 

フィルムストリップによるレンダリング過程確認
（Performanceパネル Cmd+Shift+E）
![スクリーンショット 2018-05-23 15.02.59.png](https://qiita-image-store.s3.amazonaws.com/0/2469/45ad0d50-ce55-84cb-68f8-935f335ba06d.png)

--- 

ネットワーク処理の確認（Networkパネル）
Shiftを押すとinitiators（取得元のリソース）とdependencies（取得したリソース）が確認できる
![スクリーンショット 2018-05-23 15.13.56.png](https://qiita-image-store.s3.amazonaws.com/0/2469/e851c34f-fd3c-5756-d0ec-85e64c8c381c.png)

--- 
![スクリーンショット 2018-05-23 15.17.02.png](https://qiita-image-store.s3.amazonaws.com/0/2469/582b9ee2-bc09-0596-9b3f-d50871938afd.png)

requests : 発生したリクエスト数の合計
transferred: 受信したデータの合計
DOMContentLoaded: DOMツリーの構築完了
load: DOMツリーに起因するサブリソースの取得及び評価の完了

---

ネットワーク処理に要した時間（Timingタブ）
![スクリーンショット 2018-05-23 15.33.34.png](https://qiita-image-store.s3.amazonaws.com/0/2469/0a7aad5a-85cd-6eee-b65b-e38dc95008ff.png)

---

## 基本的な対策の確認ツール
- 対象のWebページに適切な対策が行われているかをベストプラクティスにもとづいてチェック 
    - Lighthouse（Auditsパネル）
    - PageSpeedInsights

---
## 対策確認ツール（コマンドでの確認 Lighthouse）

```sh
$ npm install -g lighthouse
$ lighthouse http://otona.pro
```
![スクリーンショット 2018-05-23 15.39.07.png](https://qiita-image-store.s3.amazonaws.com/0/2469/b888a946-670e-b619-4c07-20ca245c04d7.png)
![スクリーンショット 2018-05-23 15.39.48.png](https://qiita-image-store.s3.amazonaws.com/0/2469/0501c946-6ede-36f0-dfec-ddcaa5c7064f.png)

--- 
## 対策確認ツール（コマンドでの確認 PageSpeedInsights）
```sh
$ npm install -g psi
$ psi http://otona.pro
```
![スクリーンショット 2018-05-23 15.41.42.png](https://qiita-image-store.s3.amazonaws.com/0/2469/73c07dec-fd6c-9dec-360c-0f70a207211a.png)

---
## Webページのロード速度のモニタリング
- 合成モニタリング（Synthetic Montitoring）
- リアルユーザーモニタリング（Real User Monitoring）

---
## 合成モニタリング
- 定常的な計測と詳細なレポート
- 計測用の仮想環境などから、同じ条件で定期的に繰り返し計測を行う
- 条件が固定されているので具体的な改善に役立つ

---
## リアルユーザーモニタリング
- ユーザーが体験した実測データの収集
- Webページに仕込んだ専用スクリプトによって実測データをサーバに投げて収集
- ユーザーが実際に利用したときの値や分布を収集

---
## WebPagetest
- Googleが中心となって開発しているオープンソースの速度計測サービス
    - https://www.webpagetest.org/

---
## ネットワーク処理の調査と改善
- サイズの大きいリソース
- 待機時間が長いリクエスト
- リクエスト数
- クリティカルレンダリングパス 

---
## サイズの大きいリソースの調査と改善
- 調査方法：DevToolsやPageSpeed Insightsでリソースを特定
    - サイズの大きいリソース
    - ダウンロードに時間がかかっているリソース
    - 適切な最小化が行われていないテキストリソース
    - 不必要に大きいサイズの画像

---

![スクリーンショット 2018-05-23 17.28.55.png](https://qiita-image-store.s3.amazonaws.com/0/2469/a716f9e2-05da-2de2-e792-799df61e2069.png)

---
## サイズの大きいリソースの調査と改善
- 改善方法
    - テキストリソースの最小化・圧縮
        - minifyツールで圧縮
    - デバイスに適した画像の取得と最適化
        - サーバで設定
    - JSファイルの初期コストの削減
        - webpackで分割

---
## ダウンロードに時間がかかっているリソースの調査と改善
- 調査方法：DevToolsのTimingタブのWaiting
    - ネットワーク接続のセットアップに時間がかかる
    - ダウンロードの開始までに時間がかかる

---
![スクリーンショット 2018-05-23 18.12.52.png](https://qiita-image-store.s3.amazonaws.com/0/2469/7d8a9b2a-619b-a0a3-ae0e-ab5986faab91.png)
![スクリーンショット 2018-05-23 18.13.50.png](https://qiita-image-store.s3.amazonaws.com/0/2469/0e0fd42c-46d8-0578-f25f-662837c07dda.png)

---
## ダウンロードに時間がかかっているリソースの調査と改善
- 改善方法
    - リソースへの事前接続
        - XHRによる事前リクエスト、LazyLoad
    - キャッシュに寄るリクエスト結果の再利用
        - EtagとCache-Controlを適切に設定
    - CDNからのリソース配信
        - CDN: クライントから物理距離の近いサーバから配信

---
## リクエスト数の調査と改善
- 調査方法：DevToolsのNetworkパネル
    - 発生したリクエストの総数
    - リクエストの発生要因

---
![スクリーンショット 2018-05-23 18.22.21.png](https://qiita-image-store.s3.amazonaws.com/0/2469/2787d145-cfb5-8d7e-f211-0e51e1fb4756.png)

---
## リクエスト数の調査と改善
- 改善方法
    - 不要なリクエストの削除
    - 画像の遅延ロード
    - 静的リソースの結合

---
## クリティカルレンダリングパスの調査と改善
- 調査方法：DevToolsのNetworkパネル
    - 発生したリクエストの総数
    - リクエストの発生要因

---
![スクリーンショット 2018-05-23 18.22.21.png](https://qiita-image-store.s3.amazonaws.com/0/2469/2787d145-cfb5-8d7e-f211-0e51e1fb4756.png)

---
## クリティカルレンダリングパスの調査と改善
- 改善方法
    - サブリソースのロードの最適化
        - レンダーツリーの構築に必要なCSSは優先してダウンロード
        - サブリソース全般のロードを阻害する可能性のあるJSは遅らせる

---

```html
<!doctoype html>
<html>
  <head>
    <title>title</title>
    <link rel="stylesheet" href="app.css">
    <!-- ... -->
  </head>
  <body>
    <!-- ... -->
    <script src="app.js"></script>
  </body>
</html>
```
---
- コンテンツに影響しないスクリプトの非同期実行
    - async, defer属性
    - ダウンロードが非同期に行われDOMツリーの構築処理をブロックしない

```html
<script async src="load-async.js"></script>
<script defer src="load-defer.js"></script>
```

---
![IMG_1803.jpg](https://qiita-image-store.s3.amazonaws.com/0/2469/34cc1429-4bde-4ab1-903c-0a26152f20f9.jpeg)

---

## 今後の学習の進め方
- 今回やったのは、
    - ネットワーク処理
    - レンダリング処理
    - スクリプト処理
- のうちの「ネットワーク処理」

---
## 今後の学習の進め方
- レンダリング処理
    - アニメーションが多いページ
    - イベント処理が多いページ
- スクリプト処理
    - JSの処理が多いページ