URLを打ってから表示されるまで

概要 — まず全体をつかむ

中級では、初級の4段階を実際のプロトコル名で追い直しました。上級では、その各段を「何往復かかり、どう減らせるか」という性能とキャッシュの視点で端から端まで掘り下げ、さらにHTTPそのものの進化(1.1→2→3)まで踏み込みます。ここは通信経路(ネットワーク)の深掘りを担当します。

同じ1リクエストを、サービス全体のシステム構成(フロント・バック・DB・インフラの層や、規模に耐える工夫)の側から掘るのは 1リクエストの流れ 上級です。

アニメーション『パケットの旅』を開く
💻📱 あなたのPC・スマホの中ルーター(通り道)ブラウザOSDNSサーバWebサーバ
  • ブラウザあなたの代わりにページを取りに行く注文係
  • OS機械の中の世話役。外との通信はぜんぶここを通る
  • DNSサーバ名前から住所を調べてくれる案内所
  • Webサーバページの材料を持っているお店
  • ルーター(通り道)家とインターネットの出入り口。メッセージはここを通過していく
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 12

詳細 — 1段階ずつ追う

① 住所を聞く — 名前解決の実際

中級では「近くの控えから、なければ遠くへ」を見ました。上級では、その問い合わせの型キャッシュ階層を精密にします。

  • 再帰問い合わせと反復問い合わせ — あなた→フルサービスリゾルバへは「答えを持って帰って」という再帰。リゾルバ→ルート/TLD/権威サーバへは「知っている範囲を教えて、次はどこへ聞けばいい?」という反復。役割が違う
  • 多段キャッシュ — 答えはブラウザ内・OS・リゾルバの各層に控えが残る。2回目が速いのはどこかで即答されるから
  • ネガティブキャッシュ — 「存在しない(NXDOMAIN)」という答えも一定時間キャッシュされる。無い名前を何度も引かせないため
  • 暗号化された名前解決(※1) — 通常のDNSは平文でUDPポート53を使い、経路上で覗ける。これを隠すのがDoH/DoT(HTTPS/TLSに載せる方式)
アニメーション『DNSの名前解決(再帰)』を開く
あなた(リゾルバ)ルートサーバTLDサーバ(.com)権威サーバ(example.com)
  • あなた(リゾルバ)名前からIPを調べる係。知らなければ上位へ聞きに行く
  • ルートサーバ住所帳の最上位(世界の目次)。「.com」の担当を教えてくれる
  • TLDサーバ(.com)「.com」を束ねる担当。「example.com」の担当を教えてくれる
  • 権威サーバ(example.com)この名前の最終回答(Aレコード)を持つサーバ
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 7

登場人物メモ

  • ※1 DoH/DoT — DNS over HTTPS/over TLS。名前解決の中身を暗号化して盗み見や改ざんを防ぐ

より詳しい階層と権威の仕組みは DNS を参照。

やさしく言うと(中級

🎬 アニメーション『パケットの旅』の ②〜⑤ のところです!

名前解決は「近くの控えから確認し、なければ遠くへ聞きに行く」仕組みです。必ずこの順で進みます:

  1. ブラウザは自分では調べず、OSのリゾルバ※1に「example.com のIPアドレスを教えて」と依頼する(アプリは直接ネットワークに触れず、必ずOSを通る)
  2. OSはまずキャッシュ※2を確認する。答えの控えが残っていればここで即終了——そのまま②へ進む
  3. 控えがなければ、設定されたフルサービスリゾルバ※3(通常は契約プロバイダかルーター)へ問い合わせる(主にUDPのポート53)
  4. リゾルバも知らなければ、ルートサーバ → .com のTLDサーバ → example.com の権威サーバ※4と、住所帳の階層を上から順にたどる(これが再帰問い合わせ※5)
  5. 得られた答え——Aレコード※6(= IPアドレス)——が、TTL※7の期間だけ各所に控えを残しながらブラウザまで戻ってくる
アニメーション『DNSの名前解決(再帰)』を開く
あなた(リゾルバ)ルートサーバTLDサーバ(.com)権威サーバ(example.com)
  • あなた(リゾルバ)名前からIPを調べる係。知らなければ上位へ聞きに行く
  • ルートサーバ住所帳の最上位(世界の目次)。「.com」の担当を教えてくれる
  • TLDサーバ(.com)「.com」を束ねる担当。「example.com」の担当を教えてくれる
  • 権威サーバ(example.com)この名前の最終回答(Aレコード)を持つサーバ
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 7

登場人物メモ(※の説明):

  • ※1 リゾルバ — OSに内蔵された名前解決の窓口。全アプリの「調べて」がここに集まる
  • ※2 キャッシュ — 一度調べた答えの控え。2回目のアクセスが速い理由はほぼこれ
  • ※3 フルサービスリゾルバ — あなたの代わりに世界中へ聞いて回るDNSサーバ。初級の「人脈最強の友達」の正体
  • ※4 ルート/TLD/権威サーバ — 住所帳の階層。「世界の目次 → .com の目次 → example.com 本人」の順に詳しくなる
  • ※5 再帰問い合わせ — 自分が知らなければ、他をたどってでも必ず答えを持ち帰る聞き方
  • ※6 Aレコード — 「この名前のIPアドレスはこれ」という台帳の1行
  • ※7 TTL — 控えの賞味期限。切れたら調べ直す

⚠️ イレギュラー(うまくいかないとき):

  • 名前が存在しない — 権威サーバが「そんな名前はない」と答える(NXDOMAIN)。ブラウザは「サーバが見つかりません」と表示。旅は①で終わり、②以降は始まらない
  • リゾルバが応答しない — 一定時間待って(タイムアウト)、予備のDNSサーバへ聞き直す。全滅なら接続エラー
  • 控えが古い — サーバが引っ越した直後は、TTLが切れるまで古い住所へ案内されることがある

② 電話をつなぐ — TCPとTLSの中身

接続確立は往復(RTT)※1のコストそのものです。ここを削るのが高速化の主戦場になります。

TCPの3ウェイハンドシェイク — SYN → SYN-ACK → ACK。ここで1RTTを消費し、双方向到達とシーケンス番号の起点合わせを済ませます。

アニメーション『TCPの3ウェイハンドシェイク』を開く
あなた(クライアント)サーバ
  • あなた(クライアント)通信を始めたい側。まず接続を確立しにいく
  • サーバ接続要求を受ける側
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 4

TLSハンドシェイク(HTTPSのみ)— 証明書の提示・検証と、鍵合意(現在は主にECDHE。盗聴前提でも2者だけの鍵を作る)を行います。

  • TLS 1.3 — 手順を刈り込み、1RTTで鍵合意まで完了する
  • 0-RTT再開(※2) — 一度つないだ相手には、次回待ち時間ゼロで最初のデータを乗せられる。ただし再送(リプレイ)耐性の弱さがあり、副作用のない要求に限る
アニメーション『TLSハンドシェイク(鍵の合意)』を開く
ブラウザサーバ
  • ブラウザ相手が本物か確かめ、この通信専用の共通鍵を用意したい側
  • サーバ身分証(証明書)を提示し、鍵合意に応じる側
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 4

つまりHTTPSの初回は、DNS+TCP(1RTT)+TLS(1RTT)という往復の積み重ねの上で、ようやく本題に入れます。この往復を1つでも減らす工夫が、次のHTTP進化の動機です。

登場人物メモ

  • ※1 RTT — Round Trip Time。相手まで往復する時間。距離が遠いほど1往復の重みが増す
  • ※2 0-RTT — 再接続時、鍵合意の完了を待たずに最初のデータを送る高速化。副作用のある要求には使わない

TCP・TLSが通信のどの層に乗るのかは ネットワーク層 を参照。

やさしく言うと(中級

🎬 アニメーション『パケットの旅』の ⑥〜⑧(緑の枠 = 3ウェイハンドシェイク)のところです!

IPアドレスがわかったら、そのIPのポート※1 443(HTTPSの場合)に向けて、2段階の準備をします。順序は必ず TCPが先、TLSが後です。

第1段階 — TCPの3ウェイハンドシェイク※2(初級の「3回の挨拶」の正式名):

  1. こちら → サーバ: SYNシーケンス番号※3を添えて「話したい」)
  2. サーバ → こちら: SYN-ACK(「受けた、こちらの番号はこれ」)
  3. こちら → サーバ: ACK(「確認した、始めます」)
アニメーション『TCPの3ウェイハンドシェイク』を開く
あなた(クライアント)サーバ
  • あなた(クライアント)通信を始めたい側。まず接続を確立しにいく
  • サーバ接続要求を受ける側
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 4

この3ステップ(メッセージ3本=往復にして約1.5回)で「相手は実在し、双方向に届き、番号の起点を共有した」状態になり、欠落の検知・再送・順序の保証——つまり信頼できる通信が可能になります。

第2段階 — TLSハンドシェイク※4(HTTPSの場合のみ):

  1. サーバが証明書※5を提示し、ブラウザが「本物の example.com か」を検証する
  2. 鍵合意※6(現在は主にECDHE)で、この通信専用の暗号鍵をその場で作る
  3. 以降のやり取りは、すべてこの暗号化された道の上を流れる
アニメーション『TLSハンドシェイク(鍵の合意)』を開く
ブラウザサーバ
  • ブラウザ相手が本物か確かめ、この通信専用の共通鍵を用意したい側
  • サーバ身分証(証明書)を提示し、鍵合意に応じる側
「▶ 再生」で通しで見るか、「次へ」で1手ずつ進めてください。
0 / 4

登場人物メモ(※の説明):

  • ※1 ポート — 同じ機械の中の窓口番号。Webの窓口は443(HTTPS)と80(HTTP)
  • ※2 3ウェイハンドシェイク — SYN → SYN-ACK → ACK の3ステップ(メッセージ3本=約1.5往復)。TCPの接続開始の作法
  • ※3 シーケンス番号 — データに振る通し番号。抜けや順番の乱れをこれで見つける
  • ※4 TLS(ハンドシェイク) — 通信を暗号化する層。アドレスバーの鍵マークの正体
  • ※5 証明書 — 「私は本物の example.com です」を第三者(認証局)が保証する身分証
  • ※6 鍵合意 — 盗み聞きされている前提でも、2人だけの鍵を作れる数学的な手順

⚠️ イレギュラー(うまくいかないとき):

  • 途中でデータが消えた — ACKが返らないのでTCPが自動で再送する。人間は気づかない(少し遅く感じるだけ)
  • 証明書がおかしい — 期限切れ・名義違いなどは、ブラウザが赤い警告画面で旅を中断する
  • 窓口に誰もいない — 接続拒否(RST)が返り、「このサイトにアクセスできません」になる

HTTPの進化 — 多重化とQUIC

同じ「注文と配達」でも、何本の会話を、どうさばくかが世代で変わってきました。

  • HTTP/1.1 — 1接続で1つの往復を順番に処理。keep-aliveで接続は使い回せるが、前の応答が終わるまで次が待つアプリ層のHOLブロッキング(※1)が起きる。ブラウザは接続を複数本張って無理やり並列化していた
  • HTTP/2 — 1本の接続の中をストリームに分けて多重化し、複数の要求/応答を同時に流す。ヘッダもHPACKで圧縮。ただし土台はTCPのままなので、パケット欠落時のTCPレベルのHOLブロッキングは残る
  • HTTP/3 — 転送をTCPではなくQUIC(※2、UDPの上に構築)へ載せ替える。各ストリームを独立に扱うので、1つの欠落が他を止めない。TLSも一体化して接続確立が速く、回線が変わっても接続を保つコネクション移行もできる

登場人物メモ

  • ※1 HOLブロッキング — 先頭のつかえが後続全部を足止めする現象。どの層で起きるかで解決策が変わる
  • ※2 QUIC — UDP上に再送・順序・暗号を自前で載せた新しい転送。HTTP/3の土台

③ 注文とキャッシュ判定

確立した通信路の上で注文します。上級の主役は、そもそも往復を起こさない/軽く済ませるキャッシュ判定です。

  1. ブラウザはHTTPリクエストを送る前に、手元のキャッシュが使えるかを確かめる
  2. Cache-Control: max-age(※1)の期限内なら、通信せずにキャッシュを即使用する(最速)
  3. 期限切れなら再検証(条件付きGET)へ。前回サーバがくれたETag(※2)をIf-None-Matchに、更新日時をIf-Modified-Sinceに載せて問い合わせる
  4. 中身が同じなら 304 Not Modified(本体なし)、変わっていれば 200 +新しい本体が返る

このキャッシュ判定は二段構えです。手元のブラウザキャッシュ(そのユーザー専用=private)と、経路上のCDNなど共有キャッシュ(public、みんなで再利用)。近い共有キャッシュから配れば、大元のサーバまで往復せずに済みます。

登場人物メモ

  • ※1 Cache-Control — 「何秒キャッシュしてよいか」「private/publicか」を指示する応答ヘッダ
  • ※2 ETag — 中身の版を表す短い指紋。一致すれば「変わっていない」と判定できる

共有キャッシュの地理分散と配信の仕組みは CDN を参照。

やさしく言うと(中級

🎬 アニメーション『パケットの旅』の ⑨〜⑪ のところです!

確立した通信路の上で、ようやく本題の注文です:

  1. ブラウザがHTTPリクエスト※1を送る。実体はテキストの依頼書で、GET /index.html HTTP/1.1 という1行目に、HostUser-Agent などのヘッダ※2が続く
  2. サーバはステータスコード※3 + ヘッダ + ボディ(HTML本体)を返す
  3. ブラウザはHTMLを解析(パース)※4しながら、<link>(CSS)・<img>(画像)・<script>(JS)を見つけるたびに追加リクエストを発行する
  4. この繰り返しで、1ページの表示に数十〜数百往復が発生する——だから控え(キャッシュ)とCDN※5が効く

登場人物メモ(※の説明):

  • ※1 HTTPリクエスト — 「何がほしいか」を書く定型の依頼書
  • ※2 ヘッダ — 依頼書・返事の欄外メモ。差出人(ブラウザの種類)や希望(言語・圧縮方式)を書く
※2 ヘッダの実物を見る — HTTPリクエストのどこがヘッダ?

ブラウザが実際に送っている依頼書は、たったこれだけのテキストです:

GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0
Accept: text/html
Accept-Language: ja
Cookie: session=abc123

構造は上から3つだけ。必ずこの順です:

  1. リクエストライン(1行目)— GET /index.html HTTP/1.1。「/index.html を取得(GET)したい。作法は HTTP/1.1 で」という宣言
  2. ヘッダ(2行目〜空行の手前まで)— 名前: 値 の形の欄外メモの束。上の例では Host(宛先のドメイン)、User-Agent(差出人=ブラウザの種類)、Accept(受け取れる形式)、Accept-Language(希望の言語)、Cookie(会員証)の5枚が全部ヘッダ
  3. ボディ(空行の下)— 最後の空行が「ヘッダはここまで」の合図。GETではボディは空。フォーム送信(POST)のときは、ここに入力内容が入る

返事(HTTPレスポンス)も同じ3部構造で、1行目だけが HTTP/1.1 200 OK のようなステータスラインに変わり、ボディにHTML本体が入っています。

  • ※3 ステータスコード — 返事の結果を表す3桁の数字。200=成功、404=品物がない、500=お店側の事故
※3 ステータスコードの一覧(よく見るもの)

3桁の数字は百の位がジャンルです。2xx=成功 / 3xx=案内 / 4xx=依頼側の問題 / 5xx=お店側の問題、とだけ覚えれば初見の数字も読めます。

2xx — 成功

  • 200 OK — 成功。いちばんよく見る数字
  • 201 Created — 新しく作れた(投稿・登録の成功)
  • 204 No Content — 成功したが、返す中身はない(削除の成功など)

3xx — 案内(リダイレクト)

  • 301 Moved Permanently — 恒久的に引っ越した。次からは新住所へどうぞ
  • 302 Found — 一時的にこちらへ
  • 304 Not Modified — 前回から変わっていない。手元の控え(キャッシュ)を使って

4xx — 依頼側(あなた側)の問題

  • 400 Bad Request — 依頼書の形式がおかしい
  • 401 Unauthorized — 誰だか確認できない(ログインが必要)
  • 403 Forbidden — 誰かは分かったが、権限がない
  • 404 Not Found — 品物がない
  • 429 Too Many Requests — 頼みすぎ。少し待って

5xx — お店側の問題

  • 500 Internal Server Error — お店の中で事故が起きた
  • 502 Bad Gateway — 取次役が、奥の担当から壊れた返事を受け取った
  • 503 Service Unavailable — 混雑またはメンテナンス中
  • 504 Gateway Timeout — 奥の担当からの返事が時間切れ
  • ※4 解析(パース) — 設計図を上から読み解いていく作業
  • ※5 CDN — 世界中に置いたコピー配布拠点。近い拠点から配ることで速くする仕組み

⚠️ イレギュラー(うまくいかないとき):

  • 404 Not Found — 道はつながり注文も届いたのに、品物だけがない。①や②の失敗とは起きる場所が違うのがポイント
  • 5xx — お店側の事故。あなたの操作は正しくても起きる
  • リダイレクト(301/302) — 「引っ越しました、こちらへ」。ブラウザは新しい住所へ自動でもう一度注文し直す(Networkタブだと往復が1回増えて見える)

④ 組み立てる — 描画へ橋渡し

材料が届いたら、ブラウザ内で DOM+CSSOM→レンダーツリー→レイアウト→ペイント→合成 と進みます。ここで効くのが資源の優先度です。

  • レンダーブロッキングCSS — CSSOMが揃うまで最初のペイントが止まる。だからCSSは小さく早く
  • JSの割り込み — 同期<script>はHTMLパースを止める。deferasyncや配置で緩和する
  • 描画とJSは単一メインスレッドを奪い合う——この内部は ブラウザ 上級で深掘りする
やさしく言うと(中級

🎬 アニメーション『パケットの旅』の (最後のコマ)のところです!

材料が届いたら、ブラウザの中で組み立てが始まります。ここも流れ作業です:

  1. HTMLを解析してDOMツリー※1を作る
  2. CSSを解析してCSSOM※2を作る
  3. 両者を合成して、実際に画面に出すものだけのレンダーツリー※3を作る
  4. レイアウト — どこに・何を・どの大きさで置くかを計算する
  5. ペイント — 計算どおりに描く。ここでようやくページが見える

登場人物メモ(※の説明):

  • ※1 DOMツリー — HTMLを、機械が扱える親子構造に変換したもの
  • ※2 CSSOM — CSSを同じように構造化したもの
  • ※3 レンダーツリー — 「実際に画面へ出るものだけ」を集めた最終形(非表示の要素は入らない)

⚠️ イレギュラー(割り込みと事故):

  • JavaScriptの割り込み<script> は既定ではHTMLの解析を一時停止させる。JSが重いと白い画面が続くのはこのため。defer 属性や読み込み位置が表示速度に直結する
  • CSSが遅れて届く — 一瞬だけ飾りのない「素のHTML」が見えることがある(FOUCと呼ばれる現象)

つまり「描画とJS実行は絡み合いながら進む」——ここを制御するのがフロントエンド性能改善の世界で、その入口がこのセクションです。開発者ツールのNetworkタブを開いてページを再読み込みすると、今日の旅の1往復1往復が、そのまま1行ずつ並んでいるのが見えます。

⚠️ 上級の落とし穴

  • キャッシュが古すぎる/効かなすぎるmax-ageが長すぎると更新が届かず、無ければ毎回往復。ETagでの再検証と適切な期限で釣り合わせる
  • HTTP/2にすればHOLは消える、という誤解 — 消えるのはアプリ層まで。TCPレベルのHOLはHTTP/3(QUIC)まで残る
  • 証明書チェーンの不備 — 中間証明書の配布漏れで、一部の環境だけTLS検証に失敗する(自分の端末では気づきにくい)
  • 0-RTTの誤用 — 待ち時間ゼロは魅力だが、再送されうるため副作用のある要求(注文確定など)に使うと二重実行の危険
  • 往復の見落とし — 初回はDNS+TCP+TLSと往復が積み上がる。体感速度の主因は距離(RTT)であることが多く、CDNで距離を縮めるのが効く

関連する知識

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. HTTP/2は1本の接続で多重化するのに、なお残ってHTTP/3(QUIC)で解消される「ある層の」ヘッドオブラインブロッキングとは?

2. ブラウザキャッシュの有効期限が切れたあと、ブラウザがETagを付けて再検証したところ、中身は前回から変わっていなかった。サーバは何を返すか?

3. あなた→フルサービスリゾルバへの問い合わせと、リゾルバ→ルート/TLD/権威サーバへの問い合わせの型として正しいのは?

4. DNSで「存在しない(NXDOMAIN)」という答えも一定時間キャッシュされる。この狙いとして正しいのは?

5. TLS 1.3の0-RTT再開について正しいのは?

6. HTTP/3(QUIC)が持ち、回線が変わっても接続を保てる機能はどれ?

7. 現在のTLSで主に使われ、盗聴されている前提でも2者だけの共通鍵を作れる鍵合意方式を英字5文字の略語で答えてください。

8. 「何秒キャッシュしてよいか」「private/publicか」をブラウザやCDNへ指示する応答ヘッダの名前を答えてください。

URLを打ってから表示されるまで | Kotowary