jQueryを使用してHTML要素を作成する最も効率的な方法は何ですか?


425

最近、私は多くのモーダルウィンドウポップアップを実行しており、jQueryを使用しています。ページに新しい要素を作成するために使用した方法は、圧倒的に次のようなものです。

$("<div></div>");

しかし、これはこれを行うための最良または最も効率的な方法ではないという感覚を得ています。パフォーマンスの観点からjQueryで要素を作成する最良の方法は何ですか?

この回答には、以下の提案に対するベンチマークがあります。


1
スタイルも削除してみて、スピードアップするかどうかを確認してください。私はCSSアプリケーションを見つけて、大きなページで最も遅いものを更新してくれます。
CVertex 2008年

3
時期尚早な最適化に注意してください。一度に何百ものDOM要素に対してこれを行わない場合、または非常に古いブラウザを使用している場合は、ブラウザのパフォーマンスの違いに気付かないでしょう。
Blazemonger 2012

1
@Blazemonger DOM要素を作成するためのより効率的な方法が必要だったのはそれほど多くはありませんでしたが、私がいる状況では、代替案が何であり、どれほど効率的であるかについて考えました。
Darko Z

2
jQueryはライブラリです。このため、ほとんどの場合、オーバーヘッドのパフォーマンスコストが発生します。これは、インタプリタを介して誰かと話すようなものです。生のJavaScriptを使用したくない場合を除き、$( '<div>')を記述してパフォーマンスヒットを受け入れるのがいかに速いかを利用してください。
ダニーブリス

1
jsben.ch/#/bgvCV <= このベンチマークはあなたの質問に答えるべきです
EscapeNetscape

回答:


307

私は$(document.createElement('div')); ベンチマークを使用していますが、この手法が最も速いことを示しています。これは、jQueryがそれを要素として識別して要素自体を作成する必要がないためだと推測しています。

実際には、さまざまなJavaScriptエンジンを使用してベンチマークを実行し、その結果を聴衆に比較検討する必要があります。そこから決定を下します。


16
jQueryはそれをDOMに「追加」しますか?どこ?これは私にはあまり意味がありません-divはどこに行きますか?
ストレージャー、2008年

28
jqueryで作成されたdivは、JavaScriptと同じように追加する必要があります。$( '<div>')自体は、何かにappend()するまでDOMにアタッチされません。
オーウェン、

6
@David-明らかにあなたは正しい。私がコメントを追加したのは、jQueryの学習を始めたばかりの2年ほど前のことです。あなたがする必要があるでしょうappendTo...コメントが明らかに間違っていたので、私はそれらを削除しました。
tvanfosson

16
ベンチマークリファレンスは素晴らしいですが、これは何万もの要素の作成のテストでもあります。典型的な状況でこれほど多くの要素に対処するのはいつですか。おそらく、要素の作成方法よりも大きなことを心配する必要があります。document.createElement "0.097秒で39,682回実行"、$( '<div>') "0.068秒で12,642回実行" 何かが1秒未満で何千回も実行できる場合、あなたは安全です。
ダニーブリス

20
さらに、$(document.createElement( 'div'));を使用します。あちこちに一度に1つの要素のみを作成している場合、ブラウザーで得られる実質的にわずかな利点のために書くのに時間がかかるため、効率は低くなります。技術的には、jQuery自体は、ルックアップコストとそれを使用することによって発生するオーバーヘッドのため、ライブラリとしての効率は低くなります。誰かが$( '<div>')の代わりにdocument.createElementを使用して貴重な1000分の1ミリ秒を節約しようとしている場合、$( '<div>')のためjQuery:]を使用しないでください。それを使用する理由の1つです!
ダニーブリス

163

個人的に私は(読みやすさのために)お勧めします:

$('<div>');

これまでの提案に関するいくつかの数字(safari 3.2.1 / mac os x):

var it = 50000;

var start = new Date().getTime();
for (i = 0; i < it; ++i)  {
  // test creation of an element 
  // see below statements
}
var end = new Date().getTime();
alert( end - start );                

var e = $( document.createElement('div') );  // ~300ms
var e = $('<div>');                          // ~3100ms
var e = $('<div></div>');                    // ~3200ms
var e = $('<div/>');                         // ~3500ms              

15
jquery docsから: '単一の要素を作成するときは、終了タグまたはXHTML形式を使用します。たとえば、スパンを作成するには、閉じスラッシュ/タグなしで$( "<span />")または$( "<span> </ span>")を使用します。 '
tvanfosson 2008年

6
@Owen、その動作はバグであり、機能ではありません。ガベージイン、ガベージアウト-たまたま、あなたが手に入れるガベージは許容範囲内です。ただし、関数の仕様が変更されない限り、jQueryバージョン間でこれに依存しないでください。
ストレッジャー、2008年

2
予想通り、Mac OS X Chrome(createElement()で100ミリ秒対500ミリ秒のテキスト解析)とMac OS X Firefox(350ミリ秒対1000ミリ秒)で同様の数値が表示されます。テストループを書いてくれてありがとう。
Annika Backstrom、2010

3
@tvanfossonこれは明らかに変更されており、現在のドキュメントでは次のように述べています。 )、$( "<a> </a>")または$( "<a>")— jQueryは、ネイティブJavaScript createElement()関数を使用して要素を作成します。 "
metatron

3
@MarcStober違反はありません。それはまだここにあります:http : //api.jquery.com/jQuery/#jQuery2。ドキュメントはもちろんのオプションの終了タグや迅速な閉鎖
メタトロン

155

質問:

jQueryを使用してHTML要素を作成する最も効率的な方法は何ですか?

回答:

それはそれについてですのでjQuery、私はこの(クリーンな)アプローチを使用する方が良いと思います(あなたが使用しています)

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'text':'Text Only',
}).on('click', function(){
    alert(this.id); // myDiv
}).appendTo('body');

デモ。

このように、特定の要素のイベントハンドラーを使用することもできます。

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'style':'cursor:pointer;font-weight:bold;',
    'html':'<span>For HTML</span>',
    'click':function(){ alert(this.id) },
    'mouseenter':function(){ $(this).css('color', 'red'); },
    'mouseleave':function(){ $(this).css('color', 'black'); }
}).appendTo('body');

デモ。

ただし、多くの動的要素を扱う場合はhandlers、特定の要素にイベントを追加するのを避け、代わりに、委任されたイベントハンドラーを使用する必要があります。

$(document).on('click', '.myClass', function(){
    alert(this.innerHTML);
});

var i=1;
for(;i<=200;i++){
    $('<div/>', {
        'class':'myClass',
        'html':'<span>Element'+i+'</span>'
    }).appendTo('body');
}

デモ。

そのため、同じクラス、つまり(myClass)で何百もの要素を作成して追加すると、動的に挿入されたすべての要素に対してジョブを実行するハンドラーが1つしかないため、イベント処理に消費されるメモリが少なくなります。

更新:次のアプローチを使用して動的要素を作成できるため

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    'size': '30'
}).appendTo("body");

ただし、sizeこの方法を使用して、jQuery-1.8.0または後で使用して属性を設定することはできません。ここに古いバグレポートがあります。この例をご覧ください。を使用jQuery-1.7.2して、size属性が30上記の例を使用するように設定されていることを示しますが、同じ方法をsize使用してjQuery-1.8.3、ここで属性を設定することはできません。ある非稼働フィドル。したがって、size属性を設定するには、次のアプローチを使用できます

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    attr: { size: "30" }
}).appendTo("body");

またはこれ

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    prop: { size: "30" }
}).appendTo("body");

私たちは、渡すことができattr/prop、子オブジェクトとしてではなく、それはで動作するjQuery-1.8.0 and laterバージョンチェックこの例が、それは動作しませんjQuery-1.7.2 or earlier(すべての以前のバージョンでテストされていません)。

ちなみにjQueryバグレポートから

いくつかの解決策があります。1つ目は、スペースを節約せず、コードをより明確にするため、まったく使用しないことです。

彼らは次のアプローチを使用することを勧めました(以前のも機能し、でテストされました1.6.4

$('<input/>')
.attr( { type:'text', size:50, autofocus:1 } )
.val("Some text").appendTo("body");

したがって、IMOというこのアプローチを使用することをお勧めします。この更新は、私がこの回答を読んだ/見つけた後に行われ、この回答では'Size'(capital S)'size'、それ意志だけで作業罰金、でも中version-2.0.2

$('<input>', {
    'type' : 'text',
    'Size' : '50', // size won't work
    'autofocus' : 'true'
}).appendTo('body');

propについても読みAttributes vs. Propertiesます。違いがあるため、バージョンによって異なります。


この$( '<div />'、{.........})はどのような構文ですか、探してみましたが、$( '<div>)。attr( {......})?
Rafael Ruiz Tabares

@RafaelRuizTabaresでは、$('<div>', {...})すべての属性を含むオブジェクトを渡し、属性$('<div>').attr({...})なしで要素を作成しますが、attr()後でメソッドを使用して属性を設定します。
アルファ

@TheAlphaどこに書けばよいかについての情報はどこにありますか{}?属性とイベントですが、<div>にはhtmlも使用しています。ありがとう!
ラファエルルイスタバレス

jQuery.comWebサイトの検索は、@ RafaelRuizTabaresまたはGoogleで役立つかもしれません:-)
アルファ

2
これは、最もクリーンで読みやすい方法です!おそらく高速ではありませんが、間違いなく文字列が追加される傾向があります。ありがとう@TheAlpha
Ares

37

実際、を実行している場合$('<div>')、jQueryもを使用しますdocument.createElement()

(ちょうど117行目を見てください)。

関数呼び出しのオーバーヘッドは多少ありますが、パフォーマンスが重要でない限り(数百[数千]の要素を作成している場合)、プレーンDOMに戻す理由はあまりありません。

新しいWebページの要素を作成するだけで、jQueryの方法に忠実に従うことができます。


20

多くのHTMLコンテンツ(単一のdivだけではない)がある場合は、非表示のコンテナー内のページにHTMLを作成し、それを更新して、必要に応じて表示することを検討できます。このようにして、マークアップの大部分をブラウザーで事前に解析して、呼び出されたときにJavaScriptによって行き詰まるのを防ぐことができます。お役に立てれば!


アドバイスありがとうございます。私は以前にこのアプローチを使用しましたが、この特定のケースでは、要素の作成について具体的に知りたいと思っています。
ダーコZ

20

これは質問に対する正しい答えではありませんが、それでも私はこれを共有したいと思います...

document.createElement('div')多くの要素をその場で作成してDOMに追加する場合、JQuery をジャストスキップして使用すると、パフォーマンスが大幅に向上します。


16

最適な方法を使用していると思いますが、次のように最適化できます。

 $("<div/>");

11

CPUの観点から見ると、ごくまれにしか実行されない操作のパフォーマンスをそのまま使用する必要はありません。


あなたがそれをしている頻度に依存します。
リッチブラッドショー

8
OPはモーダルポップアップを作成しています。この操作は、毎秒数千回繰り返されません。代わりに、最大で数秒ごとに1回繰り返されます。jQuery(html :: String)メソッドの使用は完全に問題ありません。状況が極端に異常でない限り、知覚されるパフォーマンスが向上する可能性は低いでしょう。最適化のエネルギーを、それを使用できるケースに費やします。さらに、jQueryは多くの点で速度が最適化されています。それで正気なことを行い、信頼できるが検証して高速であることを確認します。
yfeldblum

9

そもそもjQueryを使用する場合、要素作成のパフォーマンスの重要性は重要ではないことを理解する必要があります。

要素を実際に使用しない限り、要素を作成する実際の目的はないことに注意してください。

$(document.createElement('div'))vsのようなパフォーマンステストを行い$('<div>')、使用$(document.createElement('div'))することでパフォーマンスを大幅に向上させたくなるかもしれませんが、それはまだDOMに含まれていない要素にすぎません。

ただし、結局のところ、とにかく要素を使用したいので、実際のテストにはf.exを含める必要があります。.appendTo();

次のことを互いにテストしてみてください。

var e = $(document.createElement('div')).appendTo('#target');
var e = $('<div>').appendTo('#target');
var e = $('<div></div>').appendTo('#target');
var e = $('<div/>').appendTo('#target');

結果が異なることに気づくでしょう。ある方法が他の方法よりも優れている場合があります。これは、コンピュータ上のバックグラウンドタスクの量が時間の経過とともに変化するためです。

ここでテストしてください

したがって、結局のところ、要素を作成するための最小かつ最も読みやすい方法を選択する必要があります。そうすれば、少なくとも、スクリプトファイルは可能な限り小さくなります。おそらく、DOMで使用する前に要素を作成する方法よりも、パフォーマンスの点で重要な要素です。


私はこれが古いですけど、jQueryのための必要が最初の例ではありません:document.getElementById('target).appendChild(document.createElement('div'));
hisdrewness


7

1つの点は、実行する方が簡単かもしれないということです。

$("<div class=foo id=bar style='color:white;bgcolor:blue;font-size:12pt'></div>")

次に、jquery呼び出しですべてを実行します。


3

私はjquery.min v2.0.3を使用しています。私は以下を使用する方が良いです:

var select = jQuery("#selecter");
jQuery("`<option/>`",{value: someValue, text: someText}).appendTo(select);

次のように:

var select = jQuery("#selecter");
jQuery(document.createElement('option')).prop({value: someValue, text: someText}).appendTo(select);

最初のコードの処理時間は2番目のコードよりもはるかに短いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.