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

推薦する

アバターと国旗の統合を実現する1行のCSSコード

今日は建国記念日で、誰もが祖国の誕生日をお祝いしようとしています。毎年この時期になると、WeChat...

MySQLにおけるテーブルインデックスの定義方法と導入

概要インデックスは、テーブル内の 1 つ以上の列に基づいて DBMS によって特定の順序で作成される...

Linux プラットフォームの MySQL でリモート ログインを有効にする

開発中、MySQL へのリモートアクセスでよく問題に遭遇します。そのたびに検索する必要があり、面倒に...

MySQL 重複インデックスと冗長インデックスの例の分析

この記事では、例を使用して MySQL の重複インデックスと冗長インデックスについて説明します。ご参...

Docker を使用して pypi プライベート リポジトリを構築する方法

1. 建設1. htpasswd.txtファイルを準備するファイルには、パッケージを倉庫にアップロー...

JavaScript でツリー構造を構築するための効率的なアルゴリズムについての簡単な説明

目次導入アイデアID配列インデックスのマッピング関係を確立するツリー構造の構築原理要約する導入組織階...

Nginx Linux のインストールと展開の詳細なチュートリアル

1. Nginx の紹介Nginxは負荷分散やリバースプロキシにも使えるWebサーバーです。現在最も...

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

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

WindowsにJDK8をインストールする方法

1. ダウンロード: http://www.oracle.com/technetwork/java/...

ノードを使用して静的ファイルキャッシュを実装する方法

目次キャッシュキャッシュ位置の分類キャッシュ設定ヘッダーNodeは静的ファイルキャッシュを実装する強...

CSS に基づいて MaterialUI ボタン​​クリックアニメーションを実装し、それを React コンポーネントにカプセル化します。

序文フロントエンドフレームワークのヘビーユーザーとして、私はテクノロジーを選択する際にそのエコロジー...

ES6 ループと反復可能オブジェクトの例

この記事では、ES6 の for ... of ループについて説明します。古い方法以前は、JavaS...

HTML でシンプルな ListViews 効果を実装するためのサンプル コード

シンプルなリストビュー効果を実現するHTML結果: CSS スタイル ファイル listviewTe...

Linux サーバーで MySQL リモート接続を有効にする方法

序文以前の非MKレコードを再編成するためのMySQLの学習説明する有効になっていない場合、データベー...

MySQLはカバーインデックスを使用してテーブルリターンを回避し、クエリを最適化します。

序文カバーリング インデックスについて説明する前に、まずそのデータ構造である B+ ツリーを理解する...