JavaScript ファイルの読み込みとブロックの問題: パフォーマンス最適化のケーススタディ

JavaScript ファイルの読み込みとブロックの問題: パフォーマンス最適化のケーススタディ

まず質問させてください。HTML ページを作成するときに、外部から JS ファイルをインポートする場合、スクリプト タグはどこに配置しますか? 配置が異なると、ページの読み込みに影響しますか?
デフォルトでは、ブラウザはJavaScript スクリプトを同期的に読み込みます。つまり、レンダリング エンジンはスクリプト タグに遭遇すると停止し、スクリプトが実行されるまで待機してからレンダリングを続行します。外部スクリプトの場合は、スクリプトがダウンロードされた時刻も含める必要があります。
スクリプトが非常に大きい場合、ダウンロードと実行に長い時間がかかり、ブラウザがブロックされます。ユーザーは、ブラウザが「停止」し、しばらく空白のまま応答がないように感じるでしょう。これにより、ユーザー エクスペリエンスが非常に悪くなります。この問題には2 つの解決策があります。

①.スクリプトタグの配置を変更しますbody タグの最後、つまり </body> タグの前に配置するのが最適です。この方法はブラウザの DOM レンダリングに影響を与えず、ページ処理が完了した後に実行されます。

②.同期を非同期に変換します。ブラウザでは、スクリプトを非同期で読み込むことができます。これにより、スクリプト タグを引き続きヘッド内に配置できます。非同期読み込みの 2 つの構文を次に示します。

<script src="./1.js" 非同期></script>
<script src="./1.js" 遅延></script>

非同期と遅延

非同期とは、スクリプト タグで defer または async 属性がオンになっている場合、スクリプトが非同期で読み込まれることを意味します。ブラウザのレンダリング エンジンがこのコマンド行に遭遇すると、外部スクリプトのダウンロードを開始します。ダウンロード中、レンダリング エンジンは後続のコマンドを直接実行します。

async と defer の両方を使用すると、外部スクリプトのダウンロード中にレンダリング エンジンが停止することがなくなります。

async 属性と defer の違いは次のとおりです。

ここに画像の説明を挿入

青い線はネットワーク読み取り (スクリプトのダウンロード) を表し、赤い線は実行を表します (どちらもスクリプト用)。緑の線は HTML 解析を表します。

defer属性を使用すると、ブラウザは対応するスクリプトをすぐにダウンロードします。ダウンロード処理中もページの処理は停止しません。ドキュメントの解析が完了するまでスクリプトは実行されません

async属性を使用すると、ブラウザは対応するスクリプトをすぐにダウンロードします。ダウンロード処理中はページ処理は停止しません。ダウンロードが完了するとすぐに実行されます。実行処理中はページ処理が停止します。

属性が設定されていない場合、スクリプトが検出されると、スクリプトがダウンロードされて実行された後、ページの処理が続行されます。

[注意] async は defer よりも強力です。同じタグで両方の属性を同時に使用する場合は、async に従ってください。 ! !

複数のスクリプト

async と defer の違いは、外部スクリプト ファイルのダウンロードと実行だけでなく、複数のスクリプトが存在する場合の違いにも反映されます。
以下にコード例を示します。

外部スクリプトファイル
1.js ファイル:

// ... 大量の js コード console.log('1');

2.js ファイル:

コンソールログ('2');

メインHTMLファイル

defer を使用する:

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>js ブロッキング</title>
    <!-- defer は dom を最初に実行します -->
    <script src="./1.js" 遅延></script>
    <script src="./2.js" 遅延></script>
</head>
<本文>
    <h1>js ブロッキングはどのように機能しますか? </h1>
    <スクリプト>
        document.addEventListener('DOMContentLoaded', 関数() {
            console.log('DOMコンテンツが読み込まれました');
        })
    </スクリプト>
</本文>
</html>

コンソール実行結果:

ここに画像の説明を挿入

非同期の使用:

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>js ブロッキング</title>
    <!-- defer は dom を最初に実行します -->
    <script src="./1.js" 非同期></script>
    <script src="./2.js" 非同期></script>
</head>
<本文>
    <h1>js ブロッキングはどのように機能しますか? </h1>
    <スクリプト>
        document.addEventListener('DOMContentLoaded', 関数() {
            console.log('DOMコンテンツが読み込まれました');
        })
    </スクリプト>
</本文>
</html>

コンソール実行結果:

ここに画像の説明を挿入

コンソールの実行結果から、次のことがわかります。
defer :最初の遅延スクリプトは、2 番目の遅延スクリプトの前に実行されます (もちろん、一部のブラウザーが HTML5 標準に完全に準拠していない場合は、順番に実行されない可能性があります) 。また、これらの 2 つのスクリプトは、DOMContentLoaded イベントの前に実行されます。

async :先に完了したダウンロードがすぐに実行されます。 ! !これら 2 つのスクリプトは、DOMContentLoaded イベントがトリガーされる前には実行されない可能性がありますが、window.onload イベントの前には確実に実行されます。さらに、最初にダウンロードされたスクリプトの実行中は、他のスクリプトのダウンロードは停止せず、ダウンロードが継続されることに注意してください。

[注意] DOMContentLoaded は、DOM の読み込みが完了した後、つまりドキュメントが完全に読み込まれて解析された後にトリガーされます。
○ DOMContentLoaded の詳細については、https://www.jb51.net/article/222345.htm を参照してください。

まとめ

  1. ブロックを防ぐためのベストプラクティスは、スクリプト タグを本文の下部に配置することです。
  2. defer と async はネットワーク読み取り(ダウンロード)に関しては同じですが、どちらも非同期です(HTML 解析と比較すると)
    2 つの違いは、スクリプトがダウンロードされた後にいつ実行されるかにあります。明らかに、defer は、アプリケーション スクリプトの読み込みと実行の要件に最も近いものです。特に、スクリプト ファイル間に依存関係がある場合 (依存関係とは、この js ファイルが前の js ファイルの内容を参照する可能性があることを意味します)、読み込み順にスクリプトを実行します。 ! !
  3. async はアウトオブオーダー実行の達人です。スクリプトのロードと実行は密接に関連しているため、どのような順序で宣言しても、ロードされていればすぐに実行されます。 <br /> よく考えてみると、async は依存関係をまったく考慮しないため (最も低いレベルの順次実行でさえ)、アプリケーション スクリプトにはあまり役立ちませんが、どのスクリプトにも依存しない、またはどのスクリプトにも依存しないスクリプトには非常に適しています。最も典型的な例は次のとおりです。Google Analytics
  4. defer/async は外部スクリプトを操作する場合にのみ適しています。また、 DOM スクリプトを操作する場合は async/defer を使用しないことをお勧めします。async を使用すると、ページが読み込まれる前に js コードが実行され、例外が発生する可能性があるためです。どうしても使用する必要がある場合は、DOM を操作する必要がある js 部分を DOMContentLoaded イベント コールバックに入れて実行することができます ☺!

参照する

[1] https://blog.csdn.net/mx18519142864/article/details/82021754
[2] https://blog.csdn.net/weixin_42561383/article/details/86564715
[3] https://segmentfault.com/q/1010000000640869

これで、JavaScript ファイルの読み込みとブロックの問題のパフォーマンス最適化のケースに関するこの記事は終了です。JavaScript ファイルの読み込みとブロックの問題に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript のノンブロッキングロード、遅延、非同期の詳細な説明
  • JSファイルページの読み込み時に発生するブロッキング問題に対する完璧なソリューション
  • ブロックせずにjsをロードして、jsのロード失敗によるページ表示の影響を受けないようにします。
  • document.write を書き換えて js 広告の非ブロッキング読み込みを実現する (補足)
  • JavaScript での非ブロッキング読み込みパフォーマンス最適化ソリューション

<<:  mysql データはどこに保存されますか?

>>:  RedisとMemcacheの比較と選び方

推薦する

Linux入力サブシステムフレームワーク原理の分析

入力サブシステムフレームワークLinux 入力サブシステムは、上から下に向かって、入力サブシステム ...

MySQL 5.7.17 のインストールと設定方法のグラフィック チュートリアル (Windows)

1. ソフトウェアをダウンロードする1. MySQL の公式サイトにアクセスし、Oracle アカ...

jQueryはシンプルなコメントエリアを実装します

この記事では、参考までに、簡単なコメントエリアを実装するためのjQueryの具体的なコードを紹介しま...

setup+ref+reactive は vue3 の応答性を実装します

セットアップは、結合された API を記述するために使用されます。テンプレートが使用できるようにする...

ファイルをアップロードするための HTML フォームの「参照」ボタンを変更する方法

コードをコピーコードは次のとおりです。 <!DOCTYPE HTML PUBLIC "...

モバイルデバイスでインラインスクロールを実装するための4つのソリューションの詳細な説明

ニーズの発見領域の一部のみスクロールでき、残りの部分は移動できない場合、どのような方法を使用しますか...

Windows での Tomcat サーバーのインストールに関するチュートリアル

1 ダウンロードして準備するまず、公式ウェブサイトからTomcatをダウンロードする必要があります。...

MySQL アップグレードのベストプラクティス

MySQL 5.7 には、オンライン DDL、マルチソース レプリケーション、拡張された半同期、テー...

jsオブジェクト指向カプセル化カスケードドロップダウンメニューリストの実装手順

この例で開発されたカスケード ドロップダウン メニューは、既存の JSON データに基づいて作成され...

MySQL 自動インクリメント ID 枯渇の例

ディスプレイ定義IDテーブルに定義された自動増分IDが上限に達した場合、次のIDを申請する際に得られ...

Docker で Confluence をデプロイするための完全な手順

Confluence は有料ですが、クラックして使用できます (購入が推奨され、正規版がサポートされ...

Vue のドロップダウン ボックスのセカンダリ リンク効果を実装するためのサンプル コード

1. 成果を達成する 2. バックエンドから返されるデータ形式 「リスト」: [ { "i...

CSSはスクロールを許可しながらスクロールバーを非表示にするためにオーバーフローを設定します

CSS は、スクロールを許可しながらスクロール バーを非表示にするために Overflow を設定し...

Vueは双方向データバインディングを実装します

この記事の例では、双方向データバインディングを実装するためのVueの具体的なコードを参考までに共有し...

MySQL 8.0.12 クイックインストールチュートリアル

MySQL 8.0.12 のインストールには 2 日かかり、さまざまな問題が発生しました。以下にまと...