URLを入力してからページがレンダリングされるまでのプロセス（2）

 > [URLを入力してからページがレンダリングされるまでのプロセス（1）](https://qiita.com/Jiang_Yuehu/items/08116f3311f1cd7baca7)

## 4、TCP接続

IPアドレスを取得した後、HTTPリクエストを開始することができます。HTTPリクエストは、実際にはTCP/IPプロトコルに基づくリクエストです。データ伝送の信頼性を保証するために、接続の確立には3回のハンドシェイクが必要であり、接続の切断には4回のハンドシェイクが必要です。

 ### 3回のハンドシェイクのプロセス：
- 第一回目のハンドシェイク：クライアントがサーバーに SYN（同期）フラグが設定されたデータパケットを送信します。
- 第二回目のハンドシェイク：サーバーが受信を確認し、SYN/ACK フラグが設定されたデータパケットを返信します。
- 第三回目のハンドシェイク：クライアントが ACK フラグが設定されたデータパケットを送信し、ハンドシェイクが完了したことを確認します。

### 4回のハンドシェイクのプロセス：
- 第一回目のハンドシェイク：クライアントが FIN データパケットを送信し、サーバーへのデータ送信を終了し、シーケンス番号を指定します。クライアントは FIN_WAIT_1 状態に入ります。
- 第二回目のハンドシェイク：サーバーが FIN を受信した後、クライアントに ACK データパケットを送信し、確認シーケンス番号をクライアントのシーケンス番号 +1 として設定します。サーバーは CLOSE_WAIT 状態に入ります。
- 第三回目のハンドシェイク：サーバーがクライアントに FIN データパケットを送信し、クライアントへのデータ送信を終了します。サーバーは LAST_ACK 状態に入ります。
- 第四回目のハンドシェイク：クライアントが FIN を受信した後、TIME_WAIT 状態に入り、サーバーに ACK データパケットを送信し、受信シーケンス番号 +1 を確認します。サーバーがこの確認を受け取った後、CLOSED 状態に入り、接続が完全に切断されます。

## 5、ブラウザからサーバーへのHTTPリクエスト

> TCP接続の3回のハンドシェイクが完了した後、ブラウザとサーバー間の接続が確立され、HTTPリクエストを送信する準備が整います。HTTPリクエストは、ブラウザがサーバーのリソースを要求する方法であり、通常、リクエスト行、リクエストヘッダー、リクエストボディから構成されます。

## **リクエスト行**

リクエスト行には、メソッド、要求されるリソースのアドレス（URL）、HTTPプロトコルのバージョンが含まれます。例えば、典型的なリクエスト行は次のようになります：

``` bash
GET /index.html HTTP/1.1
```

ここでのGETはリクエストメソッドで、データの要求に使用されます。/index.htmlは要求されるリソースで、HTTP/1.1はプロトコルのバージョンです。

## **リクエストヘッダー**

リクエストヘッダーには、クライアントの環境情報やリクエストの振る舞いに関する情報が含まれます。例えば：

```
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
```

- Host：リクエストされるサーバーを指定します。
- User-Agent：リクエストするブラウザのタイプとオペレーティングシステムを識別します。
- Accept：クライアントが認識可能なコンテンツタイプを指定します。
- Accept-Language：クライアントが受け入れる言語を指定します。

## **リクエストボディ**

POSTやPUTのようなメソッドの場合、リクエストボディにはサーバーへ送信されるデータが含まれます。例えば、フォームを送信する際、リクエストボディにはフォームの内容が含まれるかもしれません：

```
username=example&password=123456
```

## **リクエストの送信**
HTTPリクエストのすべての部分が準備が整ったら、ブラウザは確立されたTCP接続を通じてリクエストをサーバーに送信します。サーバーはリクエストを受信後、リクエストされたリソースとメソッドに基づいてリクエストを処理し、HTTPレスポンスを生成してブラウザに返します。

## **レスポンスの受信**
ブラウザはサーバーからのレスポンスを受信後、レスポンスのステータスコードに基づいてリクエストが成功したかどうかを判断します。レスポンスにはヘッダーと可能なデータボディが含まれ、これらの情報はブラウザがコンテンツを正しくレンダリングして表示するのに役立ちます。

### 6、ページレンダリングプロセス

1）HTMLの解析：HTMLを解析してDOMツリーを構築します。
2）CSSの解析：CSSを解析してCSSOMツリー（スタイルツリー）を構築します。
3）レンダリングツリーの合成：DOMとCSSOMを組み合わせてレンダリングツリー（Render Tree）を生成します。
4）レイアウト計算：レンダリングツリーの構造に基づいて、各ノードの画面上のサイズや位置などの属性を計算し、レイアウト情報（Layout）を生成します。このプロセスではリフロー（回流）とリペイント（再描画）が発生します。
5）ページの描画：生成されたレイアウト情報をブラウザの描画エンジンに渡し、GPU加速を利用して画面上にピクセルを描画（Paint）します。
6）ブラウザのリフローとリペイント：ページが変更されると、ブラウザはレイアウトの再計算と描画を再度行う必要があり、これがパフォーマンス問題を引き起こす可能性があります。したがって、頻繁なDOM操作や要素スタイルの調整を避けることで、不要なリフローとリペイントを減らすべきです。

## 注意すべきなところ

（1）リフロー
リフロー（再配置とも呼ばれる）は、レイアウトツリーの再計算の本質です。レイアウトに影響を与える操作が行われた場合、ブラウザはレイアウトツリーを再計算する必要があり、リフローが発生します。連続した操作がレイアウトツリーの繰り返し計算を引き起こすのを避けるために、ブラウザはこれらの操作をマージし、すべてのJavaScriptコードの実行が完了した後に一括で計算を行います。そのため、属性の変更によるリフローは非同期で完了します。また、JavaScriptがレイアウト属性を取得するときには、最新のレイアウト情報を取得できない可能性があります。この問題を解決するために、ブラウザは属性（例：dom.clientWidth）の取得時に即座にリフローを行うことを決定しました。

（2）リペイント
リペイントの本質は、レイヤー情報に基づいて描画指令を再計算することです。可視スタイルが変更された場合、再計算が必要となり、リペイントが引き起こされます。要素のレイアウト情報も可視スタイルに含まれるため、リフローは必ずリペイントを引き起こします。

（3）まとめ
リフロー（再配置）は、DOM構造の変化や要素のスタイル変更が発生したときに起こり、スタイルとレンダリングツリーを再計算する必要があります。これはパフォーマンスを大きく消費するプロセスです。リペイントは、要素の外観スタイル（例えば背景色、枠色、文字色など）が変更されたときに発生し、この場合、ブラウザは新しいスタイルを適用して要素を描画するだけで、消費するパフォーマンスはリフローよりも少なくなります。リフローは必ずリペイントを引き起こしますが、リペイントは単独で発生することがあります。リフローのコストはリペイントよりも高く、リフローはしばしば子ノードや同じレベルのノードにも影響を及ぼすため、最適化戦略には通常、リフローを避けることが含まれます。