質問

JavaScriptがいくつかあります HEAD タグは、ページ上の最後のスクリプト (現在解析されているスクリプト) の前に、非同期で読み込むスクリプト タグを動的に挿入します。この動的に組み込まれたスクリプト タグには、DOM が利用可能になった後、すべての画像とスクリプト タグが読み込まれる前に DOM を解析する必要がある JavaScript が含まれています。すべての JS が読み込まれる前に JavaScript の実行を開始することが重要です。スクリプトがハングするとユーザー エクスペリエンスが低下するためです。つまり、待ちきれないのです DOMContentLoaded 発火するイベント。script タグを動的に含む JavaScript の最初の部分をどこに配置するかについては、柔軟性がありません。

私の質問は、 DOMContentLoaded イベント?そうでない場合、 DOMContentLoaded イベント?

役に立ちましたか?

解決

...HEAD 内の JavaScript ...前に非同期で読み込むスクリプトタグを動的に挿入します。 ページ上の最後のスクリプト...

私は仮定しています ローダースクリプトはインラインです, これは、強調表示されたビットが実際には「現在の」スクリプト要素を参照していることを意味します。ローダー。これは、ローダー スクリプト タグの前にある HTML のみが解析および解釈されるため、挿入されたスクリプト タグは実際にはまだ head ページの下部ではありません。したがって、コードを DOM 対応コールバックにラップしない限り、ターゲット スクリプトは、先行する要素に対してのみ DOM 操作を実行するように制限されます。それはあなたが最初から避けようとしているものです!

基本的に、ページが表示/スキャンできるようにすべての HTML をロードし、画像/スタイルシートのロードを開始します(これは非ブロッキングスレッドで発生します)。 それから 任意の JavaScript をロードします。1 つのアプローチは、 ターゲット スクリプトをページの下部に配置します, 、順序を正しく選択し (対話性が最初、機能強化が 2 番目、サードパーティの分析/ソーシャル メディア統合/その他の非常に重いものは最後)、ニーズに合わせて調整します。技術的には まだページの読み込みがブロックされています, しかし、とにかくページの下部に残っているのはスクリプトだけです (スクリプトは下部にあるので、IE7 のいくつかの癖を除いて、ロードされるとすぐに DOM を直接操作できます)。

関連するものがあります 暴言/概要 DOM Ready コールバックの使用と悪用に関する適切な例とタイミングに関するトリビアを提供するリンクにリンクしたいと思います。 「物語の向こう側」 優れたパフォーマンスの理由について できた まともな依存関係管理フレームワークよりも価値が低くなります。後者の主題は広すぎて 1 つの答えで説明しきれませんが、次のようなものです。 requirejs ドキュメント パターンがどのように機能するかを理解できるはずです。

おそらく、検討すべきもう 1 つのパターンは、完全なページ間を移動する「従来の」ナビゲーションではなく、コンテンツ チャンクへの非同期アクセスを利用する SPA、つまり単一ページ アプリケーションを構築することです。このパターンには、過小評価されていますが、かなり大きなパフォーマンス上の利点があります。 すべてのページで共有JavaScriptを解析して再実行する必要がありません, これにより、サードパーティの JS パフォーマンスに関する (正当な) 懸念も解決されます。結局のところ、ただ、 優れたキャッシュポリシー ロード時間は驚異的に短縮されますが、貧弱な JavaScript コードや膨大なフレームワークの実行オーバーヘッドが残ります。

アップデート: これを理解しました。特定のシナリオを念頭に置いて(つまり、マークアップ自体を制御できず、最後に実行するスクリプトになりたい場合は、 DOM への非同期スクリプト要素の挿入 0msに setTimeout 折り返し電話:

setTimeout(function(){

    //the rest is how GA operates
    var targetScript = document.createElement('script');
    targetScript.type = 'text/javascript';
    targetScript.async = true;
    targetScript.src = 'target.js';

    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(targetScript, s);

}, 0);

環境のシングルスレッドの性質により、js setTimeout コールバックは基本的に 0ms 遅延実行のキューに追加されます スレッドがビジー状態でなくなるとすぐに (より詳しい説明はこちら)。したがって、ブラウザは、すべての「優先度の高い」コードが完了するまで、ターゲット スクリプトをロードする必要性を認識せず、実行することさえ認識しません。また、スクリプト タグが追加されているときに DOM が動作するため、ターゲット スクリプト自体で DOM を明示的にチェックする必要がありません (これは、キャッシュから「即座に」ロードされる場合に便利です)。

他のヒント

以下の手法の動作は、DOMを解析しても安全なことを確保します...

  1. ウィンドウロードまたはDOMContentLoadedイベントの使用
  2. ページの下部にスクリプトを宣言または注入する
  3. スクリプトタグに "async"属性を置きます
  4. またはこれを行う:
  5. <script>
        setTimeout(function(){
         // script declared inside here will execute after the DOM is parsed
        },0);
    </script>
    
    .

    また、これらはDOMのページのロードをブロックしないではありません。

    サイズの計算や画像/ビデオが指定されていない場合は、幅/高さが指定されていない場合は、サイズの計算や位置決めを行う必要がない限り、DOMの下のスクリプトを宣言するときは、DOMContentLoadedイベントを呼び出す必要はありません。

    これが機能するいくつかのシナリオです。

    DEPENDENT DOM IS ABOVE
    <script src="jquery.js"></script>
    <script>
        $('mydom').slideDown('fast');
    </script>
    
    .

    またはこれを試してください:

    <script>
        // won't fart
        setTimeout(function(){ console.log(document.getElementById('mydom').innerHTML); },0);
    </script>
    DEPENDENT DOM IS BELOW or ABOVE (dont' matter)
    
    .

    ここにあなたが最近に気付かなかった奇妙なことの1つとして働いているSettimeoutを見ることができるように私の小さなテストです。

    http://jsfiddle.net/ffll2/

はい、DOMがロードされていることをユーザーエージェントがあなたに伝えるのを待つべきです。 しかし、そうするための複数の方法があります。

対話型と domcontentloaded onReadyStateChangeの間には違いがあります。

http://www.whAtwg.org / specs / web-apps / current-work / multipage / the-end.html ユーザーエージェントが最初に行ったことは、文書の解析を停止した後に設定しています。 文書準備「対話型」に。

ユーザーエージェントはスクリプトをロードするのを待ちません。

文書の準備が変わると、ユーザーエージェントはDocumentオブジェクトでReadyStateChangeを作成します。

だからあなたが心配しているスクリプトがインラインでない場合は、readyStateChangeに接続することができます。

クロスブラウザについての話:これは仕様です。

スクリプトロードの謎と実際のDOMの準備が細かく、どのようなものであるかは、ブラウザの不明瞭さを考慮に入れるのは、次の記事を完全に読んでいることを強くお勧めします。

http://www.html5rocks.com/en/tutorials/speed./ script-loading /

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top