ウェブページの読み込みと実行のシーケンスは?質問する

ウェブページの読み込みと実行のシーケンスは?質問する

私は Web ベースのプロジェクトをいくつか行いました。しかし、通常の Web ページの読み込みと実行のシーケンスについてはあまり考えていません。しかし、今は詳細を知る必要があります。Google や SO から回答を見つけるのは難しいので、この質問を作成しました。

サンプルページは次のようになります。

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

私の質問は次のとおりです:

  1. このページはどのように読み込まれますか?
  2. ロードの順序は何ですか?
  3. JS コードはいつ実行されますか? (インラインと外部)
  4. CSS はいつ実行(適用)されますか?
  5. $(document).ready はいつ実行されますか?
  6. abc.jpg がダウンロードされますか? それとも kkk.png だけがダウンロードされますか?

私は次のように理解しています。

  1. ブラウザは最初に HTML (DOM) を読み込みます。
  2. ブラウザは、外部リソースを上から下へ、行ごとに読み込み始めます。
  3. が満たされると<script>、読み込みがブロックされ、JS ファイルが読み込まれて実行されるまで待機してから続行されます。
  4. その他のリソース (CSS/画像) は並行して読み込まれ、必要に応じて実行されます (CSS など)。

それとも次のようになりますか:

ブラウザは HTML (DOM) を解析し、配列またはスタックのような構造で外部リソースを取得します。 HTML が読み込まれた後、ブラウザは構造内の外部リソースを並列に読み込み、すべてのリソースが読み込まれるまで実行します。 その後、DOM は JS に応じてユーザーの行動に応じて変更されます。

HTML ページの応答を取得したときに何が起こるかについて詳しく説明してくれる人はいますか? これはブラウザによって異なるのでしょうか? この質問に関する参考資料はありますか?

ありがとう。

編集:

Firefox で Firebug を使用して実験してみました。次の画像のように表示されます。代替テキスト

ベストアンサー1

編集: 2022年です。Webページの読み込みと実行、ブラウザの動作について詳しく知りたい場合は、 https://browser.engineering/ ( https://github.com/browserengineering/bookでオープンソース化)をご覧ください。


あなたのサンプルによると、

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

おおよその実行フローは次のようになります。

  1. HTML文書がダウンロードされる
  2. HTML文書の解析が始まります
  3. HTML解析は<script src="jquery.js" ...
  4. jquery.jsダウンロードされ解析される
  5. HTML解析は<script src="abc.js" ...
  6. abc.jsダウンロードされ、解析され、実行される
  7. HTML解析は<link href="abc.css" ...
  8. abc.cssダウンロードされ解析される
  9. HTML解析は<style>...</style>
  10. 内部CSSルールが解析され定義される
  11. HTML解析は<script>...</script>
  12. 内部のJavaScriptが解析され実行される
  13. HTML解析は<img src="abc.jpg" ...
  14. abc.jpgダウンロードされ表示される
  15. HTML解析は<script src="kkk.js" ...
  16. kkk.jsダウンロードされ、解析され、実行される
  17. HTML文書の解析終了

ブラウザの動作により、ダウンロードが非同期かつ非ブロッキングになる場合があることに注意してください。たとえば、Firefox には、ドメインごとに同時リクエストの数を制限する設定があります。

また、コンポーネントがすでにキャッシュされているかどうかによって、近い将来のリクエストでコンポーネントが再度リクエストされない場合があります。コンポーネントがキャッシュされている場合、コンポーネントは実際の URL ではなくキャッシュから読み込まれます。

解析が終了し、ドキュメントの準備が整い、読み込まれると、イベントonloadが起動されます。したがって、onloadが起動されると、が$("#img").attr("src","kkk.png");実行されます。つまり、

  1. ドキュメントの準備が整い、onload が起動されました。
  2. Javascript実行ヒット$("#img").attr("src", "kkk.png");
  3. kkk.pngダウンロードされ、読み込まれる#img

この$(document).ready()イベントは、実際にはすべてのページ コンポーネントが読み込まれ準備完了したときに発生するイベントです。詳細については、http://docs.jquery.com/Tutorials:Introducing_$(document).ready()を参照してください。

編集 - この部分では、平行かどうかという部分についてさらに詳しく説明します。

デフォルトでは、そして私の現在の理解では、ブラウザは通常、HTML パーサー、Javascript/DOM、および CSS の 3 つの方法で各ページを実行します。

HTML パーサーはマークアップ言語の解析と解釈を担当するため、他の 2 つのコンポーネントを呼び出すことができる必要があります。

たとえば、パーサーが次の行に遭遇すると:

<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>

パーサーは 3 つの呼び出しを行います。2 つは Javascript への呼び出し、1 つは CSS への呼び出しです。最初に、パーサーはこの要素を作成し、この要素に関連するすべての属性とともに DOM 名前空間に登録します。次に、パーサーはこの特定の要素に onclick イベントをバインドするために呼び出しを行います。最後に、CSS スレッドをもう一度呼び出して、この特定の要素に CSS スタイルを適用します。

実行はトップダウンでシングル スレッドです。Javascript はマルチ スレッドのように見えますが、実際はシングル スレッドです。外部の Javascript ファイルを読み込むときに、メインの HTML ページの解析が中断されるのは、このためです。

ただし、CSS ルールは常に適用されているため、CSS ファイルは同時にダウンロードできます。つまり、要素は常に定義された最新の CSS ルールで再描画され、ブロックが解除されます。

要素は解析された後にのみ DOM で使用可能になります。したがって、特定の要素を操作する場合、スクリプトは常にウィンドウの onload イベントの後、またはそのイベント内に配置されます。

次のようなスクリプトはエラーを引き起こします (jQuery の場合)。

<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>
<div id="mydiv">Hello World</div>

スクリプトが解析されたときに、#mydiv要素がまだ定義されていないためです。代わりに、次のようにします。

<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>

または

<script type="text/javascript">/* <![CDATA[ */
  $(window).ready(function(){
                    alert($("#mydiv").html());
                  });
/* ]]> */</script>
<div id="mydiv">Hello World</div>

おすすめ記事