ホームページ ウェブフロントエンド jsチュートリアル JQuery each() 関数はループ DOM のパフォーマンスをどのように最適化しますか

JQuery each() 関数はループ DOM のパフォーマンスをどのように最適化しますか

May 16, 2016 pm 05:47 PM
jquery

jQuery の具体的な実装を知らずに、jQuery を使用するレベルに留まると、非常に簡単に問題が発生します。このフレームワークの API 設定が人々を迷わせている疑いがあるため、私は最近 jQuery をあまり使いたくないのです。

コードをコピー コードは次のとおりです。

$.fn.beautifyTable = function(options) ) {
//デフォルトの構成項目を定義し、オプションでそれらをオーバーライドします。
return this.each(function() {
var table = $(this),
tbody = table.children ('tbody')、
tr = tbody.children('tr')、
th = tbody.children('th')、
td = tbody.children('td'); >//単一のコンテンツ クラス
table.addClass(option.tableClass);
th.addClass(options.headerClass); //1
td.addClass(options.cellClass); >//奇数行と偶数行 class
tbody.children('tr:even').addClass(options.evenRowClass); //3
tbody.children('tr:odd').addClass(options. oddRowClass); //4
//Alignment
tr.children('th,td').css('text-align', options.align); //5
//マウスホバーを追加
tr.bind('mouseover', addActiveClass); //6
tr.bind('mouseout',removeActiveClass); //7
//クリックして色を変更します
tr.bind( 'クリック', toggleClickClass); //8
});
一般に、このコードは優れており、アイデアが明確で、ロジックが明確で、やりたいことがコメントで明確に説明されています。しかし、作者によると、テーブルに 120 行がある場合、IE はスクリプトの実行時間が長すぎることをすでに反映しています。パフォーマンスの観点から見ると、この機能の効率は決して高くないか、あるいは極端に低いことは明らかです。

そこで、コードレベルから分析を始めました。これは、標準的な jQuery プラグイン関数です。 return this.each(function( ) { .. };) という形式のコードがあります。 ; 作者がこのコードを書いたときに何も考えずにスクリプトに従っていたのではなく、jQuery の関数が何をするのかを理解したはずです。

簡単に言うと、jQuery.fn のほとんどの関数は each への呼び出しであり、選択された要素を自然に走査し、要素に対して指定された操作を実行します。したがって、上記のコードを見て、実行されたトラバーサルの数を確認してください。120 行のみが選択されており、各行に 6 つの列と 1 行のヘッダーがあると仮定します。
Traverse th、headerClass の数を追加します。要素は6です。
td をトラバースし、cellClass を追加すると、要素の数は 6*120=720 になります。
すべての tr から奇数を見つけるには、すべての tr を 1 回走査する必要があり、要素数は 120 です。
奇数の tr をトラバースし、evenRowClass を追加します。要素の数は 120/2=60 です。
すべての tr から偶数を見つけるには、すべての tr を 1 回走査する必要があり、要素数は 120 です。
偶数の tr をトラバースし、oddRowClass を追加すると、要素の数は 120/2=60 になります。
th と td をすべて走査し、text-align を追加します。要素の数は 120*6 6=726 です。
すべての tr を走査し、mouseover イベントを追加します。要素の数は 120 です。
すべての tr をトラバースし、mouseout イベントを追加します。要素の数は 120 です。
すべての tr をトラバースし、クリック イベントを追加します。要素の数は 120 です。
便宜上、トラバーサル中の要素へのアクセスには 10 ミリ秒かかると仮定します。では、この関数には合計でどれくらいの時間がかかるのでしょうか?この関数は合計 2172 個の要素を検出し、21720 ミリ秒、つまり 21 秒かかりました。明らかに、IE はスクリプトに時間がかかりすぎたと報告するはずです。

効率が低い理由がわかったので、当然のことながら、コード内のコメントの数字に従ってループをマージする方法を見つける必要があります。上記では、少なくとも次の点をマージできます:
3 と 4 は 120 60 120 60 から 120 まで 1 つのサイクルに結合でき、240 の削減になります。 1、2、5 は 1 つのサイクルに結合できます。 6 720 726 から 726 に、726 の減少です。6. 7 と 8 を 1 つのサイクルに組み合わせることができ、120 120 120 から 120 に変化し、240 の減少になります。さらに、3、4 と 6、7、8 を 1 つのサイクルに組み合わせることができ、120 ずつ減少し続けます。累積的に、合計 240 726 240 120 = 1326 要素演算、合計 13260 ミリ秒が削減されました。最適化後、関数の消費時間は 21720-13260=8460 ミリ秒、つまり 8 秒になります。
ここで質問があるかもしれませんが、テーブルの構造から、すべての th 要素と td 要素は tr 内にある必要があります。なぜ 1、2、5 の 3 ステップのサイクルも tr に入れたらよいのでしょうか。ループを作成してネストされたループを形成すると、より高速になるのではないでしょうか?
ここでこれが行われない主な理由は 2 つあります。
まず、1、2、5 をどこに配置しても、すべての th 要素と td 要素への 1 回のアクセスは減りません。
一方、セレクター $('th, td') は、sizzle での getElementsByTagName 関数への 2 回の呼び出しに変換されます。1 回目はすべての th を取得し、2 回目はすべての td を取得してから収集します。合併の彼ら。 getElementsByTagName は組み込み関数であるため、この関数はループを持たないと考えることができます。つまり、複雑さは O(1) です。同じコレクションのマージには、演算である Array の関連関数が使用されます。メモリ上での計算量も O(1) です。

逆に、セレクター $('th, 'td) が tr 要素のループで使用されている場合、関数がどの要素で呼び出されるかに関係なく、getElementsByTagName が tr 要素で 2 回呼び出されます。 , 関数の実行時間は同じなので、trのループ時に使用すると関数呼び出しが119*2多くなり、効率は上がらずに下がってしまいます。
シズル セレクターの基本的な知識も、jQuery コードの最適化に役立つ非常に重要な側面であることがわかります。
JavaScript にすべてをさせないでください。

前回の基本的な最適化によれば、時間は 21 秒から 8 秒に短縮されましたが、8 秒という数字は明らかに受け入れられません。
コードをさらに分析すると、実際、ループ トラバーサルは言語レベルで行われ、その速度は非常に高速であることがわかります。各要素に対して実行される操作は、jQuery によって提供される関数です。トラバーサルと比較すると、ほとんどのリソースが消費されます。トラバーサル中に要素にアクセスするのに 10 ミリ秒かかる場合、率直に言って、addClass の実行には少なくとも 100 ミリ秒が消費されます。

したがって、効率をさらに最適化するには、要素に対する操作を減らすことから始める必要があります。コードを注意深く検討した結果、この関数のスタイルには、少なくとも次のような多くの変更が加えられていることがわかりました。
Add class to all th.
すべての TD にクラスを追加します。
tr の奇数行と偶数行にクラスを追加します。
すべての th と td に text-align スタイルを追加します。
実際、CSS 自体には子孫セレクターがあり、ブラウザーによる CSS のネイティブ解析は、JavaScript で要素にクラスを 1 つずつ追加するよりもはるかに効率的であることがわかっています。

したがって、CSS が制御可能である場合、この関数には 2 つの構成項目 headerClass と cellClass を含めるべきではなく、可能な限り CSS で構成する必要があります:
コードをコピーします コードは次のとおりです:

.Beautiful-table th { /* headerClass の内容*/ }
. beautiful -table td { /* content of cellClass*/ }

さらに、tr の奇偶行スタイルについては、一部のブラウザでは n 番目の子疑似クラスを使用して実装できます。ただし、この疑似クラスをサポートしていないブラウザでのみ、機能検出を使用して addClass を使用してスタイルを追加できます。もちろん、IE シリーズを最適化したいだけの場合は、この項目は無視して構いません。

nth-child 擬似クラスを検出するには、次のアイデアを使用できます。スタイルシートを作成し、#test span:nth-child (odd) { display: block などのルールを作成します。 ; } 。対応する HTML 構造、ID テストを持つ div を作成し、その中に 3 つのスパンを配置します。

スタイルシートと div を DOM ツリーに追加します。 1 番目と 3 番目のスパンの実行時の表示スタイルを確認し、ブロックになっている場合は、疑似クラスがサポートされていることを示します。作成したスタイルシートと div を削除し、プローブの結果をキャッシュすることを忘れないでください。最後に、すべての th 要素と td 要素に text-align スタイルを追加することも、CSS を通じて最適化できます。どの配置が追加されるかわからないため、さらにいくつかのスタイルを記述します。
コードをコピー コードは次のとおりです。 :

/* CSS スタイル*/
. beautiful-table-center th,. beautiful-table-center td { text-align: center ! important }
. beautiful- table-rightright th, . beautiful-table-rightright td { text-align: rightright ! important; }
. beautiful-table-left th,. beautiful-table-left td { text-align: left ! important }
/* javascript */
table.addClass('Beautiful-table-' options.align);

もちろん、上記の最適化は CSS を制御することに基づいています。 、CSS スタイルにアクセスできない場合、たとえば、これは完全に制御できないサードパーティによって使用される一般的なプラグイン機能である場合はどうすればよいでしょうか。完全に不可能というわけではありません。
document.styleSheets など、ページ内のすべての CSS ルールを見つけます。すべてのルールを調べて、構成アイテム内の headerClass、cellClass などを取り出します。必要ないくつかのクラスのすべてのスタイルを抽出し、それらを自分で新しいセレクター (Beautiful-table th など) に組み立てます。作成したセレクターを使用して新しいスタイルシートを生成し、DOM ツリーに追加します。あとは、 beautiful-table クラスをテーブルに追加するだけで完了です。

もちろん、上記のアプローチは実際にはかなり時間がかかります。結局のところ、スタイルシートを調べてスタイルシートを作成する必要があります。効率の向上に大きく役立つかどうかは、ページのサイズに応じて異なります。これを使用するかどうかは、機能設計者の具体的なニーズによって異なります。

一般に、できるだけ少ない JavaScript を実行し、より多くのスタイル設定タスクを CSS に渡すことで、ブラウザーのレンダリング エンジンがそれを完了し、この関数は addClass と css の呼び出しに対してさらに最適化できると仮定します。には 100 ミリ秒かかりますが、この最適化により、元の 120 726 = 846 の操作が直接削除され、84600 ミリ秒の時間が節約されます (もちろん誇張ですが、関数全体の消費量という観点からすると、これは実際には非常に大きな部分です)。

この記事では、jQuery のさまざまな実装レベルの最適化のみを目的としており、jQuery の実行プロセス全体の分析、詳細な導入、最適化の方向性についてのみ説明し、いくつかの基本的な最適化方法については触れません。 as: まずテーブル全体を DOM ツリーから削除し、すべての操作が完了した後で再描画を減らすためにテーブル全体を DOM に戻します。正しいイベント バブリング モデルによって引き起こされる繰り返しイベント関数の実行を減らすために、mouseover と Mouseout を MouseEnter と MouseLeave に変更します。 th や td などの単純な要素の選択では、ネイティブの getElementsByTagName を使用することが優先され、セレクターのシズル分析の時間を排除します。

最後に、この記事では、フロントエンド開発者にとって、ブラウザはブラックボックスかもしれないが、事前にある程度理解できていれば、多くのフレームワーク、ツール、ライブラリがオープンであることを説明したいと思います。それを使用することは、間違いなく個人の技術を向上させ、最終製品の品質を最適化するのに役立ちます。「それを知っているが、その理由を知らない」という状況は非常にタブーです。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

jQueryのリファレンスメソッドを詳しく解説:クイックスタートガイド jQueryのリファレンスメソッドを詳しく解説:クイックスタートガイド Feb 27, 2024 pm 06:45 PM

jQuery 参照方法の詳細説明: クイック スタート ガイド jQuery は、Web サイト開発で広く使用されている人気のある JavaScript ライブラリであり、JavaScript プログラミングを簡素化し、開発者に豊富な機能を提供します。この記事では、jQuery の参照方法を詳しく紹介し、読者がすぐに使い始めるのに役立つ具体的なコード例を示します。 jQuery の導入 まず、HTML ファイルに jQuery ライブラリを導入する必要があります。 CDN リンクを通じて導入することも、ダウンロードすることもできます

jQueryでPUTリクエストメソッドを使用するにはどうすればよいですか? jQueryでPUTリクエストメソッドを使用するにはどうすればよいですか? Feb 28, 2024 pm 03:12 PM

jQueryでPUTリクエストメソッドを使用するにはどうすればよいですか? jQuery で PUT リクエストを送信する方法は、他のタイプのリクエストを送信する方法と似ていますが、いくつかの詳細とパラメータ設定に注意する必要があります。 PUT リクエストは通常​​、データベース内のデータの更新やサーバー上のファイルの更新など、リソースを更新するために使用されます。以下は、jQuery の PUT リクエスト メソッドを使用した具体的なコード例です。まず、jQuery ライブラリ ファイルが含まれていることを確認してから、$.ajax({u

jQueryで要素の高さ属性を削除するにはどうすればよいですか? jQueryで要素の高さ属性を削除するにはどうすればよいですか? Feb 28, 2024 am 08:39 AM

jQueryで要素の高さ属性を削除するにはどうすればよいですか?フロントエンド開発では、要素の高さ属性を操作する必要が生じることがよくあります。要素の高さを動的に変更する必要がある場合や、要素の高さ属性を削除する必要がある場合があります。この記事では、jQuery を使用して要素の高さ属性を削除する方法と、具体的なコード例を紹介します。 jQuery を使用して高さ属性を操作する前に、まず CSS の高さ属性を理解する必要があります。 height 属性は要素の高さを設定するために使用されます

jQuery のヒント: ページ上のすべての a タグのテキストをすばやく変更する jQuery のヒント: ページ上のすべての a タグのテキストをすばやく変更する Feb 28, 2024 pm 09:06 PM

タイトル: jQuery ヒント: ページ上のすべての a タグのテキストをすばやく変更する Web 開発では、ページ上の要素を変更したり操作したりする必要がよくあります。 jQuery を使用する場合、ページ内のすべての a タグのテキスト コンテンツを一度に変更する必要がある場合があります。これにより、時間と労力を節約できます。以下では、jQuery を使用してページ上のすべての a タグのテキストをすばやく変更する方法と、具体的なコード例を紹介します。まず、jQuery ライブラリ ファイルを導入し、次のコードがページに導入されていることを確認する必要があります: &lt

jQuery を使用してすべての a タグのテキスト コンテンツを変更する jQuery を使用してすべての a タグのテキスト コンテンツを変更する Feb 28, 2024 pm 05:42 PM

タイトル: jQuery を使用して、すべての a タグのテキスト コンテンツを変更します。 jQuery は、DOM 操作を処理するために広く使用されている人気のある JavaScript ライブラリです。 Web 開発では、ページ上のリンク タグ (タグ) のテキスト コンテンツを変更する必要が生じることがよくあります。この記事では、この目標を達成するために jQuery を使用する方法を説明し、具体的なコード例を示します。まず、jQuery ライブラリをページに導入する必要があります。 HTML ファイルに次のコードを追加します。

徹底した分析: jQuery の長所と短所 徹底した分析: jQuery の長所と短所 Feb 27, 2024 pm 05:18 PM

jQuery は、フロントエンド開発で広く使用されている高速、小型、機能豊富な JavaScript ライブラリです。 2006 年のリリース以来、jQuery は多くの開発者にとって最適なツールの 1 つとなっていますが、実際のアプリケーションでは、いくつかの利点と欠点もあります。この記事では、jQuery の長所と短所を詳しく分析し、具体的なコード例で説明します。利点: 1. 簡潔な構文 jQuery の構文設計は簡潔かつ明確であるため、コードの読みやすさと記述効率が大幅に向上します。例えば、

jQuery における eq の役割と応用シナリオを理解する jQuery における eq の役割と応用シナリオを理解する Feb 28, 2024 pm 01:15 PM

jQuery は、Web ページでの DOM 操作やイベント処理を処理するために広く使用されている人気のある JavaScript ライブラリです。 jQueryではeq()メソッドを利用して指定したインデックス位置の要素を選択しますが、具体的な使い方と応用シーンは以下の通りです。 jQuery では、 eq() メソッドは、指定されたインデックス位置にある要素を選択します。インデックス位置は 0 からカウントされます。つまり、最初の要素のインデックスは 0、2 番目の要素のインデックスは 1 などとなります。 eq() メソッドの構文は次のとおりです。 $("s

jQuery 要素に特定の属性があるかどうかを確認するにはどうすればよいですか? jQuery 要素に特定の属性があるかどうかを確認するにはどうすればよいですか? Feb 29, 2024 am 09:03 AM

jQuery 要素に特定の属性があるかどうかを確認するにはどうすればよいですか? jQuery を使用して DOM 要素を操作する場合、要素に特定の属性があるかどうかを判断する必要がある状況がよく発生します。この場合、jQuery が提供するメソッドを使用してこの関数を簡単に実装できます。以下では、jQuery 要素が特定の属性を持つかどうかを判断するために一般的に使用される 2 つの方法を紹介し、具体的なコード例を添付します。方法 1: attr() メソッドと typeof 演算子 // を使用して、要素に特定の属性があるかどうかを判断します

See all articles