最新のブラウザの <script> タグは、クラシックとノンブロッキングの 2 つの新しいタイプに分類されます。これら 2 つのタグを使用してページをできるだけ早く読み込む方法について説明します。 </p> <p>1. ブロックしているスクリプトはどこに行くのでしょうか? </p> <p> <script> タグの標準バージョンは、ブロッキング タグと呼ばれることがあります。この用語は文脈の中で理解する必要があります。最新のブラウザは、ブロッキング <script> タグを見つけると、ブロッキング ポイントをスキップして、ドキュメントの読み取りと他のリソース (スクリプトとスタイルシート) のダウンロードを続行します。ただし、スクリプトがダウンロードされて実行されるまで、ブラウザーはチョークポイントを超えてこれらのリソースを評価しません。したがって、Web ドキュメントの </p> タグ内に 5 つのブロック <script> タグがある場合、5 つのスクリプトすべてがダウンロードされて実行されるまで、ユーザーにはページ タイトルのみが表示されます。それだけでなく、これらのスクリプトが実行されたとしても、ブロック ポイントより前のドキュメントの部分しか表示されません。 <body> タグでロードを待っているすべての機能を確認したい場合は、document.onreadystatechange のようなイベントにイベント ハンドラーをバインドする必要があります。 <p>上記の理由に基づいて、ページの <body> タグの最後にスクリプトを配置することがますます一般的になってきています。このようにして、ユーザーはページをより速く表示できる一方で、スクリプトはイベントがトリガーされるのを待たずに DOM にアクティブにアクセスすることもできます。ほとんどのスクリプトにとって、この「移動」は大きな改善です。 <p>しかし、すべてのスクリプトが同じというわけではありません。スクリプトを読み進める前に、自分自身に 2 つの質問をしてください。 <p>このスクリプトが <body> タグ内のインライン JavaScript によって直接呼び出される可能性はありますか?答えは明らかかもしれませんが、それでも確認する価値はあります。 <p>このスクリプトはレンダリングされたページの外観に影響しますか? Typekit ホスト フォントは一例です。 Typekit スクリプトをドキュメントの最後に配置すると、ページ テキストはドキュメントが読み取られた直後とスクリプトの実行時に 2 回レンダリングされます。 <p>上記の質問に対する答えの 1 つが「はい」である限り、スクリプトは <head> タグに配置する必要があります。それ以外の場合は、ドキュメントは次のようになります。 これにより読み込み時間は確かに大幅に短縮されますが、bodyScripts.js が読み込まれる前にユーザーがページを操作する機会が与えられる可能性があることに注意してください。 <p>2. スクリプトの早期読み込みと遅延実行<p> ほとんどのスクリプトは <body> に配置することをお勧めします。これにより、ユーザーは Web ページをより速く表示できるだけでなく、バインドする前に DOM を操作する必要がなくなります。準備完了" "イベントの費用。ただし、このアプローチには、ドキュメント全体が読み込まれるまでブラウザがこれらのスクリプトを読み込めないという欠点もあり、これが低速接続で送信される大きなドキュメントのボトルネックになる可能性があります。 <p>理想的には、スクリプトはドキュメントのロードと同時にロードされる必要があり、DOM のレンダリングには影響しません。この方法では、スクリプトは <script> タグの順序ですでに読み込まれているため、ドキュメントの準備ができたらスクリプトを実行できます。 <p>ここまで読んだ方は、そのようなニーズを満たすカスタム Ajax スクリプト ローダーを作成したくなるはずです。ただし、ほとんどのブラウザは、より単純なソリューションをサポートしています。 <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false"><html> <head> <!--metadata and stylesheets go here --> <script src="headScripts.js"></scripts> </head> <body> <!-- content goes here --> <script src="bodyScripts.js"></script> </body> </html></pre><div class="contentsignin">ログイン後にコピー</div></div></p> defer 属性を追加することは、ブラウザに次のように指示することと同じです。「今すぐこのスクリプトの読み込みを開始してください。ただし、ドキュメントの準備が整い、defer 属性を持つ以前のすべてのスクリプトの実行が完了するまで待ってからドキュメント内で実行してください。」遅延スクリプトを <head> タグに配置すると、スクリプトを <body> タグに配置することによるすべての利点が得られるだけでなく、大きなドキュメントの読み込み速度も大幅に向上します。 <p></p>欠点は、すべてのブラウザが defer 属性をサポートしているわけではないことです。つまり、ドキュメントのロード後に遅延スクリプトを実行できるようにするには、すべての遅延スクリプト コードを jQuery の $(document).ready などの構造にカプセル化する必要があります。 <p></p>前のセクションのページ例は次のように改善されました: <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false"><script defer src = "deferredScript.js"></pre><div class="contentsignin">ログイン後にコピー</div></div></p> deferredScript のカプセル化は重要であることに注意してください。そのため、ブラウザーが defer をサポートしていない場合でも、deferredScript はドキュメントの準備完了イベントが終了するまで実行されません。ページのメインコンテンツが数キロバイトよりはるかに大きい場合は、価格を支払う価値があります。 <p></p>3. スクリプトの並列読み込み<p></p> ページの読み込み時間をミリ秒単位で気にする完璧主義者にとって、遅延は味のない醤油のようなものかもしれません。以前のすべての遅延スクリプトの実行が完了するまで待つ必要はなく、これらのスクリプトを実行する前にドキュメントの準備が完了するまで待つ必要もありません。これらのスクリプトをできるだけ早くロードして実行したいだけです。これが、最新のブラウザーが async 属性を提供する理由です。 <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false"><script async src = "speedyGonzales.js"> <script async src = "roadRunner.js"></pre><div class="contentsignin">ログイン後にコピー</div></div><p>如果说defer 让我们想到一种静静等待文档加载的有序排队场景,那么async 就会让我们想到混乱的无政府状态。前面给出的那两个脚本会以任意次序运行,而且只要JavaScript 引擎可用就会立即运行,而不论文档就绪与否。<br/>对大多数脚本来说,async 是一块难以下咽的鸡肋。async 不像defer那样得到广泛的支持。同时,由于异步脚本会在任意时刻运行,它实在太容易引起海森堡蚁虫之灾了(脚本刚好结束加载时就会蚁虫四起)。<br/>当我们加载一些第三方脚本,而且也不在乎它们谁先运行谁后运行。因此,对这些第三方脚本使用async 属性,相当于一分钱没花就提升了它们的运行速度。<br/>上一个页面示例再添加两个独立的第三方小部件,得到的结果如下:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false"><html> <head> <!-- metadata and stylesheets go here --> <script src="headScripts.js"></scripts> <script src="deferredScripts.js" defer></script> </head> <body> <!-- content goes here --> <script async defer src="feedbackWidget.js"></script> <script async defer src="chatWidget.js"></script> </body> </html></pre><div class="contentsignin">ログイン後にコピー</div></div><p>这个页面结构清晰展示了脚本的优先次序。对于绝大多数浏览器,DOM的渲染只会延迟至headScripts.js 结束运行时。进行DOM渲染的同时会在后台加载deferredScripts.js。接着,在DOM 渲染结束时将运行deferredScripts.js 和那两个小部件脚本。这两个小部件脚本在那些支持async 的浏览器中会做无序运行。如果不确定这是否妥当,请勿使用async!</script>
以上がクラシックタグとノンブロッキング