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の比較と選び方

推薦する

フレームウィンドウ間の関連付けとハイパーリンクのターゲット属性の使用を実装する方法

フレーム ウィンドウの関連付けを実現するには、次に示すように、ハイパーリンクの「ターゲット」ウィンド...

ウェブサイトデザインにおいて非常に重要な概念であるdiv+floatの分析

ウェブサイトの構築では、HTML と CSS に関するさまざまな問題に常に遭遇します。ウェブサイト ...

Linux で txt を mysql にインポートする方法

序文昨日、小さなプロジェクトを書いていたときに、txt ドキュメントのデータを mysql データベ...

データ構造 - ツリー (III): 多方向検索ツリー B ツリー、B+ ツリー

多方向探索ツリー完全二分木の高さ: O(log2N)、ここで2は対数完全なM方向探索木の高さ: O(...

MySQL で遅いクエリ SQL を見つけて最適化する詳細な例

目次1. 遅いクエリSQLを見つけて最適化する方法a. スローログに基づいてスロークエリSQLを見つ...

Docker ネットワークの原理とカスタム ネットワークの詳細な分析

Docker はホストマシン上のブリッジを仮想化します。コンテナを作成して起動すると、各コンテナには...

初心者向けのMySQLデータベースとテーブルDDLの作成と操作の学習

目次1. データベースを操作する1.1 データベースを作成する1.2 データベースをクエリする1.3...

MySQL 8.0.23 インストールの超詳細なチュートリアル

目次序文1. 公式サイトからMySQLをダウンロードする2. 解凍ファイルを設定する3. 初期化4....

Reactのようなフレームワークをゼロから作成する

最近、インターネットで「Build your own React」という記事を見ました。著者は、シン...

dl、dt、dd はいつ使用するのが適切ですか?

dl:定義一覧定義リストdt:定義タイトルタイトルを定義するdd:定義説明定義の説明dt は情報のタ...

Electronで不規則な形状の透明部分をクリックする実装

目次不規則なフォームの実装透明な部分をクリックする不規則なフォームの実装ここでは円形フォームを実装し...

MySQL空間関数を使用してロケーションパンチインを実装するための完全な手順

序文プロジェクトの要件は、ユーザーの現在の位置が特定の地理的位置範囲内にあるかどうかを判断することで...

Mysql 中国語ソートルールの説明

MySQL を使用する際、フィールドをソートしたりクエリしたりすることがよくあります。通常は、中国語...

MySQLはPartition関数を使用して水平分割戦略を実装します。

目次1件のレビュー2 水平分割の5つの戦略2.1 ハッシュ2.2 範囲2.3. キー2.4. リスト...

スクロールバーを非表示にしながらもスクロール効果を維持する純粋な CSS (モバイルと PC)

携帯モバイル ページは Chrome および Safari とのみ互換性があればよいため、カスタム ...