HTMLとリソースがどのように読み込まれるかを理解します

HTMLとリソースがどのように読み込まれるかを理解します

このブログのすべてのコンテンツは、クリエイティブ コモンズ ライセンスの下でライセンスされています。このコンテンツを引用する場合は、ソースであるZhu Taoを維持し、非営利で引用してください。

導入

私はいくつかの Web ベースのプロジェクトを完了し、フロントエンドの js、css、html とバックエンドの python/php がどのように相互作用し、ブラウザーがそれらを実行するかを学びました。しかし、1 つの疑問が常に頭に残っていました。

HTML には複数の外部リソース (js、css、flash、画像など) があります。これらのリクエストはいつダウンロードされ、実行されるのでしょうか?

私が書いた js がいつ実行されるのかはわかりませんし、多くの高パフォーマンスの提案が html の下部にある </body> の前に js を置くことになっている理由もわかりません。

よく分からない場合は、ぜひ私と一緒に学んでください。

具体的な分析

まず、次のようなサンプル HTML ページを見てみましょう。

 <html>
  <ヘッド>
   <script src= "/static/jquery.js"タイプ= "text/javascript" ></script>
   <script src= "/static/abc.js"タイプ= "text/javascript" >
   </スクリプト>
   <link rel= "スタイルシート" type= "text/css" href= "/static/abc.css" ></link>
   <スクリプト>
    $(ドキュメント).ready(関数(){
     $( "#img" ).attr( "src" , "/static/kkk.png" );
   });
   </スクリプト>
  </head>
  <本文>
  <div>
  <img id= "img" src= "/static/abc.jpg"スタイル= "幅:400px;高さ:300px;" />
  <script src= "/static/kkk.js"タイプ= "text/javascript" ></script>
  </本文>
</html>

以下のリソースがあります:

  1. 3 つの外部 js ファイル、1 つのインライン js コード
  2. 外部 CSS ファイル 1 つ、インライン CSS コード 1 つ
  3. 1 つの画像ファイルと、js によって要求された 1 つの画像

合計で 6 つの HTTP リクエストがあります。

分析する前に、次に示すように、この HTML に対する Firefox のリクエストの結果を見てみましょう。

/do/uploads/allimg/091203/2217550.png

次の図に示すように、この HTML に対する Chrome (Linux) のリクエストの結果を見てみましょう (図は比較的小さいので、新しいタブで開くことができます)。

/do/uploads/allimg/091203/2217551.png

まず分析し、次にこれら 2 つのリクエストの結果の違いについて説明します。

リクエスト分析

まず、以下の説明は主に私自身の Google 検索、友人への相談、SO や IRC での入手に基づいていることを指摘しておきます。私は関連する仕様を読んでいません (もちろん読みたいと思っていますが、関連する仕様をご存知の場合はメッセージを残してください。ありがとうございます)。また、その正確性や精度を保証することはできません。リスクはご自身の責任でお願いします :D。

関連する調査に基づいて私が理解しているのは、URI リクエストの場合、ブラウザは次のリクエストと実行の順序に従うということです。

  1. 1つのスレッドがDOM(つまりHTML、HTML内の外部リソースに関係なく)をダウンロードします。
  2. 別のスレッドがダウンロードされた DOM の分析を開始し、外部リソース (js、css、画像など) のダウンロードを開始します。
  3. 3 番目のスレッド (存在する場合) は、スレッド 2 によってダウンロードされるリソース以外の外部リソースをダウンロードします。
  4. より多くの接続が許可されると、より多くのスレッドが他のリソースのダウンロードを継続します。

リクエストが同時に持つことができる接続 (スレッド) の数は、ブラウザによって異なります。http1.1 標準では、同じサーバー/プロキシ (つまり、ホスト名) に対して 2 つを超える接続は許可されないと規定されていますが、実際のブラウザ実装では、詳細は次のとおりです。

ファイアフォックス2:2
ファイアフォックス3:6
オペラ 9.26: 4
Opera 9.5 ベータ: 4
Safari 3.0.4 Mac/Windows: 4
IE7:2
IE8:6

ですので、実際の状況を踏まえて上記のダウンロード順序をご検討ください。

次に、実行順序(js 実行、css アプリケーションなど)を見てみましょう。

  1. ブラウザがjsコードを「見る」限り、それは実行されます
  2. ブラウザは下から下へ、行ごとに実行されます
  3. js コードが関数またはオブジェクト内にある場合、その関数またはオブジェクトが呼び出されたときにのみ実行されます。
  4. いわゆる直接コード(関数やオブジェクトにないコード)は上から下へ順番に実行されます。
  5. CSSファイルがダウンロードされると、対応するスタイルもDOMに適用されます。
  6. DOM がダウンロードされた後、onload または jQuery の $(document).ready() が実行されます。

実際のブラウザでは、<script> タグに遭遇すると、Firefox などの他のスレッドのダウンロードが自動的にブロックされます。このため、Web 開発では <script> タグを </body> の前に置くことが推奨されることが多いのです。

ただし、すべてのブラウザがブロックするわけではありません。たとえば、Chrome は他の接続をブロックしません。そのため、特定の負荷は特定のブラウザ実装を参照する必要があります。

ほとんどの場合、パフォーマンスが向上するため、<script></script> タグを </body> の前に置くことをお勧めします。

FirefoxとChromeのリクエスト分析

上の 2 つの図のリクエスト応答図をもう一度見てみましょう。

ファイアフォックス

以下の機能があります:

  1. まずHTMLをダウンロードしてください
  2. htmlのダウンロードが完了したら、外部ファイル(js、css、img)を上から下にダウンロードします。
  3. jsは他の外部ファイルのダウンロードをブロックします
  4. 他のファイルも並行してダウンロードされます

クロム

以下の機能があります:

  1. まずHTMLをダウンロードしてください
  2. 外部ファイル(js、css、img)を上から下にダウンロードします
  3. 各リソースのダウンロード順序は並列です

js を並列にダウンロードできるとしたら、DOM の下のコードが最初に実行されるのでは、と疑問に思うかもしれません。まず、次の js が最初にダウンロードされたとしても、上から下への全体的な実行順序には影響しないことは確かです。ブラウザはこの順序を維持します。Chrome のこの方法は、将来のブラウザのトレンドでもあり、これが Chrome が高速化できる理由の 1 つです。

興味深いエピソード

この質問をした後、私は多くの調査を始めました。友人に相談したり、SO で質問したり、Firefox IRC でも質問したりしました。

私に答えてくれた友人たちは皆、とても辛抱強く答えてくれました。しかし、彼らのほとんどは私に質問をしました。「Web 開発を行うときに、なぜこれらの詳細を知る必要があるのですか?」

私はいまだにそのような疑問に困惑しています。優れたプログラマーは、方法だけでなく、何を、そしてなぜを知る必要があると私は常に信じてきました。

方法を知っているということは、他の人が提供するものを簡単に使用して開発できる、有能なプログラマーであることを意味します。

理解するということは、舞台裏で物事がどのように行われているかに注意を払い始めることを意味します。時間が経つにつれて、徐々に経験豊富なプログラマーになります。

理由を知ることは、あなたがハッカーになる道を歩み、徐々に技術専門家の道へと進んでいることを意味します。長期的には、大きく成長します。ハッカーになる方法を参照してください。

表面的な幸せにとどまるのではなく、細部や本質的な幸せを楽しみましょう。

結論は

ブラウザは、独立系 (Firefox、Chrome、IE、Opera、Safari) か、特定のカーネルに基づくもの (Aoyou、Sogou、TT、360 など) かを問わず、すべての主要メーカーが競争している市場ですが、ブラウザがより強力になり、標準に準拠し、応答が高速化されるなど、Web プログラマーとしての私たちの生活がはるかに良くなることは間違いありません。

この記事の一部の詳細はまだ不明瞭なので、後で別の記事を書いて、より徹底的かつ明確な説明をする予定です。

議論を歓迎します。

追記

今回は出費を惜しみませんでした。以前から SO 評判ポイントを 400 ポイント近く貯めていたため、すぐに 150 人を派遣して最も満足のいく回答を見つけてもらいました。

詳細については以下を参照してください。

Web ページの読み込みと実行のシーケンスは?

投稿内にさらに詳しい回答がありますので、参考にしてください。

参考文献

  1. Web ページの読み込みと実行のシーケンスは?
  2. JavaScript DOM ロード イベント、実行シーケンス、および $(document).ready()
  3. JavaScript 実行順序
  4. 初心者 - CSS はいつ適用されますか?
PDF版パッケージのダウンロード

<<:  MySQL 同期遅延が発生したときに Seconds_Behind_Master が 0 のままになる理由

>>:  VMwareワークステーションとデバイス/資格情報の非互換性によって発生する起動エラーについて

推薦する

Vue での this.$set の動的データバインディングのケーススタディ

インターネット上の this.$set の説明はわかりにくいと感じます。単一データ、オブジェクト、配...

@media レスポンシブ CSS を使用してさまざまな画面に適応する例

定義と使用@media クエリを使用すると、さまざまなメディア タイプに異なるスタイルを定義できます...

ラベルタグの使用時に発生する問題の分析と解決策

最近何かをするときにラベル タグを使用しました。以前はラベル タグをほとんど使用していなかったため、...

Vue ユニットテストに関する予備調査

目次序文なぜユニットテストを導入するのですか?ユニットテストの概要テスト開発パターン1. テスト駆動...

MySQLにインデックスを追加する方法

インデックスの簡単な紹介は次のとおりです。インデックスを追加する目的は、データベース クエリのパフォ...

Linux のリンク解除機能とファイルの削除方法

1. リンク解除機能ハード リンクの場合、unlink はディレクトリ エントリを削除し、inode...

TypeScript の基本型の紹介

目次1. 基本タイプ2. オブジェクトタイプ2.1 配列2.2 タプル2.3 オブジェクト3. 型推...

Vueは画像のドラッグアンドドロップ機能を実装します

この記事の例では、画像のドラッグアンドドロップ機能を実現するためのVueの具体的なコードを参考までに...

MySQL の文字セット utf8 を utf8mb4 に変更する方法

MySQL 5.5 の場合、文字セットが設定されていない場合、MySQL のデフォルトの文字セットは...

Nexus を使用して jar パッケージをプライベート サーバーに追加する方法

なぜ Nexus プライベート サーバーを構築する必要があるのでしょうか。その理由は非常に簡単です。...

Vue ページレンダリングにおけるキーの適用例チュートリアル

導入フロントエンドプロジェクトの開発プロセスでは、el-table によって表示される結果列がコンポ...

js を使用して年カルーセル選択効果をネイティブに実装する例

序文js を使用して、年の回転選択効果を実現します。では早速、写真を見てみましょう。 1. アイデア...

Vue.js の watch メソッドと computed メソッドの違いの詳細な例

目次序文導入1. 作用機序2. 自然から3. 時計と計算の比較4. メソッドはデータロジックの関係を...

MySQLデータベースにパスワードを入力した後にフラッシュバックする問題の解決策

パスワード入力後にMySQLデータベースがクラッシュする問題と解決策1 ケースの説明最近、基本的な機...

Docker に Tomcat をインストールし、Springboot プロジェクトの WAR パッケージをデプロイする方法

簡単です。チュートリアルを見てください。ブロガー1. まずdockerを起動するサービスdocker...