7

<script>ページの読み込み後に、head要素に動的にいくつかのタグを追加しています。スクリプトが非同期で読み込まれることは理解していますが、追加された順序で解析されることを期待できますか?

Firefoxで期待される動作が見られますが、SafariやChromeでは見られません。Chrome開発者ツールとFirebugでドキュメントを見ると、どちらも次のように表示されます-

<html>
  <head>
    ...
    <script type="text/javascript" src="A.js"></script>
    <script type="text/javascript" src="B.js"></script>
  </head>
  ...
</html>

ただし、リソース読み込みビューを見ると、chromeはサーバーから最初に返された方を解析しているように見えますが、firebugは、Bがサーバーから最初に返された場合でも、スクリプトタグが追加された順序で常にそれらを読み込みます。

Chrome / Safariが指定された順序でファイルを解析することを期待する必要がありますか?OSX10.6.3でChrome5.0.375.29ベータ版を使用する

編集(10/5/10):私が解析と言うとき、私は実行することを意味します-積極的な解析の多くの利点を見ることができます-thx rikh

編集(11/5/10):わかりました。それでは、以下のjuandopazoによるテストをまとめました。しかし、私は以下を含むものの組み合わせを追加しました

  1. javascriptを使用してスクリプト要素をヘッドに直接追加します。(テストA-> D)
  2. jqueryのappend()メソッドを使用してスクリプト要素をヘッドに追加します。(テストE-> H)
  3. jqueryのgetScript()メソッドを使用してスクリプトを「ロード」します。(テストI-> L)

また、スクリプトタグの「async」属性と「defer」属性のすべての組み合わせを試しました。

ここからテストにアクセスできます-http://dyn-script-load.appspot.com/、およびソースを表示して、テストがどのように機能するかを確認します。ロードされたスクリプトは、update()関数を呼び出すだけです。

最初に注意することは、上記の1番目と3番目のメソッドのみが並行して動作することです。2番目はリクエストを順番に実行します。あなたはここでこれのグラフを見ることができます-

画像1-リクエストライフサイクルの
グラフリクエストライフサイクルグラフhttp://dyn-script-load.appspot.com/images/dynScriptGraph.png

jqueryのappend()アプローチがgetScript()呼び出しもブロックすることも興味深いです。すべてのappend()呼び出しが完了するまで実行されないことがわかります。その後、すべてが並行して実行されます。これに関する最後の注意点は、jQueryのappend()メソッドは、スクリプトタグが実行されると、ドキュメントヘッドからスクリプトタグを削除するように見えることです。最初の方法のみがスクリプトタグをドキュメントに残します。

Chromeの結果

その結果、テストに関係なく、Chromeは常に最初に返されるスクリプトを実行します。これは、jQueryのappend()メソッドを除くすべてのテストが「失敗」することを意味します。

画像2-Chrome5.0.375.29ベータ結果
Chromeの結果http://dyn-script-load.appspot.com/images/chromeDynScript.png

Firefoxの結果

ただし、Firefoxでは、最初の方法が使用され、非同期がfalse(つまり設定されていない)の場合、スクリプトは確実に順番に実行されるようです。

画像3-FF3.6.3結果
FF結果http://dyn-script-load.appspot.com/images/ffDynScript.png

SafariはChromeと同じようにさまざまな結果をもたらすように見えることに注意してください。これは、理にかなっています。

また、開始->終了時間を短縮するために、遅いスクリプトでは500ミリ秒の遅延しかありません。ChromeとSafariがすべてで失敗するのを確認するには、数回更新する必要がある場合があります。

これを行う方法がなければ、データを並行して取得する機能を利用していないように思われます。また、(Firefoxが示すように)そうすべきでない理由はありません。

4

6 に答える 6

3

私自身の質問に答えて申し訳ありませんが、それはしばらくの間であり、私たちは解決策を思いつきました。私たちが思いついたのは、JavaScriptをjsonオブジェクトに含まれるテキストとして同時にロードし、すべてがロードされたらeval()を使用して正しい順序で実行することでした。同時ロードと順序付き実行。ユースケースによっては、jsonが必要ない場合があります。大まかに言って、これが私たちがしたことを示すいくつかのコードです-

// 'requests' is an array of url's to javascript resources
var loadCounter = requests.length;
var results = {};

for(var i = 0; i < requests.length; i++) {
   $.getJSON(requests[i], function(result) {
      results[result.id] = result;
      ...
      if(--loadCounter == 0) finish();
   });
}

function finish() {
  // This is not ordered - modify the algorithm to reflect the order you want
  for(var resultId in results) eval(results[resultId].jsString);
}
于 2010-07-30T14:45:46.343 に答える
0

a.jsからb.jsをロードして100%確実にすることができます...特にスクリプトの同期ajaxロードでは、この質問に対する決定的な答えが欲しいのですが。

于 2010-05-10T16:44:54.803 に答える
0

私が理解しているように、それらはドキュメントに表示されている順序で実行されることを意図しています。一部のブラウザは、順不同で解析を実行できる場合がありますが、それでも正しい順序で実行する必要があります。

于 2010-05-10T16:07:11.010 に答える
0

いいえ、両方が読み込まれるまで、すべてのブラウザが両方のスクリプトの実行を延期することを期待することはできません(**特に動的に追加する場合)。

B.jsロードされた後にのみコードを実行する場合は、変数を設定するコールバックと、その変数が設定されているかどうかを確認するコールバックA.jsを追加するのが最善の策です。次に、必要な関数を実行します。 (ロードされていない場合は、ロードされるまで定期的にチェックするタイマーを開始します)。onloadA.jsB.jsB.jsA.js

于 2010-05-10T16:10:44.427 に答える
0

ダウンロードの順序と実行の順序は同じではありません。ページでは、B.jsが最初にダウンロードされた場合でも、ブラウザのエンジンはA.jsがページの処理を続行するのを待ちます。

スクリプトは、ドキュメントに表示された順序だけでなく、表示された場所でも確実に処理されます。

そうでない場合、jQueryを使用する小さなスクリプトがjQueryライブラリの前にダウンロードされて処理されると、多くのエラーが発生することを想像してみてください。

また、jsファイルで「document.write」を実行すると、スクリプトが宣言されている場所に表示されます。スクリプト宣言の後に表示されるDOMオブジェクトにもアクセスできません。

これが、スクリプトが処理されるとすぐにブラウザのレンダリングエンジンが停止するため、スクリプトの実行が早すぎないようにし、ページの「認識される読み込み時間」を短縮するために、ページの一番下にスクリプトを配置することをお勧めする理由です。

マイク

編集:JavaScriptで動的に追加された場合、時間内に追加された順序で処理されると思います。

于 2010-05-10T16:15:53.340 に答える
0

YUI 3のようにモジュールを動的にロードする小さなライブラリで作業しているときに、これを調査していました。ここで、コンテンツをdivに挿入するだけの2つのスクリプトをロードする小さなテストを作成しました。1つは一般的なJSファイルで、もう1つは実行を3秒待つPHPファイルです。

http://www.juandopazo.com.ar/tests/asyn-script-test.html

ご覧のとおり、スクリプトは、すべてのブラウザーで、DOMに追加した順序ではなく、読み込みが完了したときに実行されます。

于 2010-05-10T16:49:35.280 に答える