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

推薦する

WeChatミニプログラムマップの使い方を詳しく解説

この記事の例では、WeChatアプレットマップで使用される具体的な実装コードを参考までに共有していま...

両端の CSS レイアウトのサンプルコード (親の負のマージンを使用)

最近、開発中に両端が揃ったレイアウトに遭遇しました。レイアウトはパーセンテージに基づいていました。以...

Angularコンポーネントのライフサイクルの詳しい説明(パート2)

目次1. ビューフック1. ngAfterViewInit および ngAfterViewCheck...

HTML における水平および垂直の中央揃え方法の詳細な説明 (基礎)

序文馬を書いていたとき、水平方向と垂直方向の中央揃えの方法について、誰もあまり知らなかったと思います...

MySQLのビューの詳細な説明

ビュー: MySQL のビューはテーブルと多くの類似点があります。ビューも複数のフィールドと複数のレ...

Vue+echarts で積み上げ棒グラフを実現

この記事では、積み上げ棒グラフを実装するためのVue+echartsの具体的なコードを参考までに紹介...

Nginx+Apache の動的および静的分離の導入の詳細な例

Nginx の動的および静的分離の概要Nginx は静的処理能力が強力ですが、動的処理能力が不十分で...

HTML 5 スタイルシートのリセット

この CSS リセットは、Eric Meyers の CSS リセットに基づいて変更されており、特に...

HTMLヘッダータグの使用に関する詳細な説明

HTMLはヘッドとボディの2つの部分で構成されています** ヘッド内のタグはヘッドタグです** タイ...

一般的な XHTML タグの使用方法の紹介

XHTML には多くのタグがありますが、頻繁に使用されるのはごくわずかであり、習得する必要があるのは...

MySQLインデックスの詳細

1. インデックスの原則インデックスは、列内の特定の値を持つ行をすばやく見つけるために使用されます。...

事例を通してLinux NFSの仕組みを詳細に分析

前回の記事に引き続き、web02 サーバーを作成し、web01 サーバーと web02 サーバーの ...

Centos 7.4 サーバーの時刻同期設定方法 [NTP サービスに基づく]

この記事では、CentOS 7.4 サーバーで時刻同期を構成する方法について説明します。ご参考までに...

MySQL データベースの詳細な説明 (Ubuntu 14.0.4 LTS 64 ビットベース)

1. MySQLデータベースの構成と関連概念まず、MySQL はリレーショナル データベースである...