Apa cara paling efisien untuk membuat elemen HTML menggunakan jQuery?

425

Baru-baru ini saya telah melakukan banyak jendela pop-up dan apa yang tidak, yang saya gunakan jQuery. Metode yang saya gunakan untuk membuat elemen baru pada halaman telah sangat sejalan:

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

Namun, saya merasa ini bukan metode terbaik atau paling efisien untuk melakukan ini. Apa cara terbaik untuk membuat elemen di jQuery dari perspektif kinerja?

Jawaban ini memiliki tolok ukur untuk saran di bawah ini.

Darko Z
sumber
1
Eksperimen dengan menghapus gaya juga dan lihat apakah itu mempercepat. Saya menemukan aplikasi CSS dan pembaruan memperlambat segalanya pada halaman besar bagi saya.
CVertex
3
Waspadalah terhadap pengoptimalan prematur - jika Anda tidak melakukan ini untuk ratusan elemen DOM sekaligus, atau menggunakan browser SANGAT lama, maka Anda mungkin tidak akan melihat perbedaan dalam kinerja browser.
Blazemonger
1
@ Blazemonger Bukan karena saya membutuhkan metode yang lebih efisien untuk membuat elemen DOM, tetapi situasi yang saya alami membuat saya merenungkan apa alternatifnya dan seberapa efisien mereka.
Darko Z
2
jQuery adalah perpustakaan - Anda hampir selalu mengeluarkan biaya kinerja overhead untuk alasan ini: itu seperti berbicara dengan seseorang melalui seorang juru bahasa. Kecuali jika Anda ingin menggunakan JavaScript mentah, manfaatkan seberapa cepat menulis $ ('<div>') dan terima hit performa.
Danny Bullis
1
jsben.ch/#/bgvCV <= patokan ini harus menjawab pertanyaan Anda
EscapeNetscape

Jawaban:

307

Saya menggunakan $(document.createElement('div')); Benchmarking menunjukkan teknik ini adalah yang tercepat. Saya berspekulasi ini karena jQuery tidak harus mengidentifikasinya sebagai elemen dan membuat elemen itu sendiri.

Anda harus benar-benar menjalankan benchmark dengan mesin Javascript yang berbeda dan menimbang audiens Anda dengan hasilnya. Buat keputusan dari sana.

strager
sumber
16
jQuery "menambahkan" ke DOM? Dimana? Ini tidak masuk akal bagi saya - ke mana div pergi?
strager
28
div dibuat di jquery harus ditambahkan seperti di javascript. $ ('<div>') dengan sendirinya tidak dilampirkan ke DOM sampai Anda menambahkan () ke sesuatu.
Owen
6
@ David - jelas Anda benar. Saya akan perhatikan bahwa saya menambahkan komentar sekitar 2 tahun yang lalu tepat ketika saya mulai belajar jQuery. Anda perlu melakukan appendTo, ... Karena komentarnya jelas salah, saya telah menghapusnya.
tvanfosson
16
Referensi pembandingannya bagus, tetapi ini juga menguji penciptaan puluhan ribu elemen. Kapan Anda akan pernah berurusan dengan banyak elemen dalam situasi yang khas? Kemungkinannya adalah, Anda memiliki hal-hal yang lebih besar untuk dikhawatirkan daripada cara membuat elemen. document.createElement "Berlari 39.682 kali dalam 0,097 detik", sedangkan $ ('<div>') "Berlari 12.642 dalam 0,068 detik." Saya akan mengatakan jika sesuatu dapat berjalan ribuan kali dalam waktu kurang dari satu detik, Anda aman.
Danny Bullis
20
Selanjutnya, menggunakan $ (document.createElement ('div')); Saya akan mengatakan itu kurang efisien karena butuh waktu lebih lama untuk menulis untuk sejumlah kecil manfaat yang akan Anda dapatkan di browser jika Anda hanya membuat satu elemen pada suatu waktu di sana-sini. Secara teknis, jQuery sendiri kurang efisien sebagai perpustakaan karena biaya pencarian dan biaya overhead yang Anda keluarkan dengan menggunakannya. Jika seseorang sangat ingin menyelamatkan seperseribu detik yang berharga dengan menggunakan document.createElement alih-alih $ ('<div>'), maka mereka tidak boleh menggunakan jQuery:], karena $ ('<div>') adalah salah satu alasan Anda menggunakannya!
Danny Bullis
163

secara pribadi saya sarankan (agar mudah dibaca):

$('<div>');

beberapa angka pada saran sejauh ini (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              
Owen
sumber
15
Dari dokumen jquery: 'Saat membuat elemen tunggal gunakan tag penutup atau format XHTML. Misalnya, untuk membuat rentang gunakan $ ("<span />") atau $ ("<span> </span>") alih-alih tanpa tanda garis miring / tag. '
tvanfosson
6
@Wen, perilaku itu adalah bug, bukan fitur. Sampah masuk, sampah keluar - Kebetulan sampah yang Anda terima dapat diterima. Namun, jangan mengandalkan antar versi jQuery, kecuali spesifikasi untuk fungsi berubah.
strager
2
Seperti yang diharapkan, melihat angka yang sama di Mac OS X Chrome (100 ms untuk createElement () vs penguraian teks 500 ms) dan Mac OS X Firefox (350 ms vs 1000 ms). Terima kasih telah menulis loop tes.
Annika Backstrom
3
@tvanfosson Tampaknya ini telah berubah, dalam dokumen saat ini dikatakan: "Ketika parameter memiliki satu tag (dengan tag penutup opsional atau penutupan cepat) - $ (" <img /> ") atau $ (" <img> " ), $ ("<a> </a>") atau $ ("<a>") - jQuery membuat elemen menggunakan fungsi JavaScript createElement () asli. "
metatron
3
@MarcStober Jangan tersinggung. Itu masih di sini: http://api.jquery.com/jQuery/#jQuery2 . Dokumen menyebutkan tag penutup opsional atau penutupan cepat
metatron
155

Pertanyaan:

Apa cara paling efisien untuk membuat elemen HTML menggunakan jQuery?

Menjawab:

Karena sudah sekitar jQuerymaka saya pikir lebih baik menggunakan pendekatan (bersih) ini (Anda menggunakan)

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

DEMO.

Dengan cara ini, Anda bahkan dapat menggunakan penangan acara untuk elemen tertentu seperti

$('<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');

DEMO.

Tetapi ketika Anda berurusan dengan banyak elemen dinamis, Anda harus menghindari menambahkan peristiwa handlersdalam elemen tertentu, sebagai gantinya, Anda harus menggunakan event handler yang didelegasikan, seperti

$(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');
}

DEMO.

Jadi, jika Anda membuat dan menambahkan ratusan elemen dengan kelas yang sama, yaitu ( myClass) maka lebih sedikit memori akan digunakan untuk penanganan acara, karena hanya ada satu penangan yang akan melakukan pekerjaan untuk semua elemen yang dimasukkan secara dinamis.

Pembaruan: Karena kita dapat menggunakan pendekatan berikut untuk membuat elemen dinamis

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

Tetapi sizeatribut tidak dapat diatur menggunakan pendekatan ini menggunakan jQuery-1.8.0atau yang lebih baru dan ini adalah laporan bug lama , lihat contoh ini menggunakan jQuery-1.7.2yang menunjukkan bahwa sizeatribut diatur untuk 30menggunakan contoh di atas tetapi menggunakan pendekatan yang sama kita tidak dapat mengatur sizeatribut menggunakan jQuery-1.8.3, di sini adalah biola yang tidak bekerja . Jadi, untuk mengatur sizeatribut, kita bisa menggunakan pendekatan berikut

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

Atau yang ini

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

Kita bisa lulus attr/propsebagai objek anak-anak tetapi berfungsi dalam jQuery-1.8.0 and laterversi memeriksa contoh ini tetapi tidak akan berhasil masukjQuery-1.7.2 or earlier (tidak diuji di semua versi sebelumnya).

BTW, diambil dari jQuerylaporan bug

Ada beberapa solusi. Yang pertama adalah untuk tidak menggunakannya sama sekali, karena tidak menghemat ruang apa pun dan ini meningkatkan kejelasan kode:

Mereka menyarankan untuk menggunakan pendekatan berikut ( bekerja di yang sebelumnya juga, diuji dalam 1.6.4)

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

Jadi, lebih baik menggunakan pendekatan ini, IMO. Pembaruan ini dibuat setelah saya membaca / menemukan jawaban ini dan dalam jawaban ini menunjukkan bahwa jika Anda menggunakan 'Size'(capital S)alih-alih 'size'itu hanya akan berfungsi dengan baik , bahkan diversion-2.0.2

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

Baca juga tentang prop , karena ada perbedaan Attributes vs. Properties,, itu bervariasi melalui versi.

Alfa
sumber
Sintax macam apa ini $ ('<div />', {.........}), saya sudah mencarinya dan saya menemukan beberapa yang mirip menggunakan $ ('<div>) .attr ( {......})?
Rafael Ruiz Tabares
@RafaelRuizTabares, di dalam $('<div>', {...})Anda melewati objek yang berisi semua atribut dan di dalam $('<div>').attr({...})Anda membuat elemen tanpa atribut apa pun selain mengatur atribut menggunakan attr()metode nanti.
The Alpha
@TheAlpha di mana saya dapat menemukan info tentang apa yang dapat saya tulis di dalam {}? Karena saya melihat mereka adalah atribut dan acara tetapi untuk <div> Anda menggunakan html juga. Terima kasih!
Rafael Ruiz Tabares
Cari jQuery.comsitus web bisa bermanfaat @RafaelRuizTabares, atau google :-)
The Alpha
2
Sejauh ini, ini adalah cara terbersih yang paling mudah dibaca! Mungkin bukan cara yang cepat tetapi kesalahan kurang tentu rawan penambahan string. Terima kasih @TheAlpha
Ares
37

Sebenarnya, jika Anda melakukannya $('<div>'), jQuery juga akan digunakandocument.createElement() .

(Lihat saja pada baris 117 ).

Ada beberapa fungsi-panggilan overhead, tetapi kecuali kinerja sangat penting (Anda membuat ratusan [ribuan] elemen), tidak ada banyak alasan untuk kembali ke DOM biasa .

Hanya membuat elemen untuk halaman web baru mungkin merupakan kasus di mana Anda akan tetap berpegang pada cara jQuery melakukan sesuatu.

edwin
sumber
20

Jika Anda memiliki banyak konten HTML (lebih dari sekadar satu div), Anda dapat mempertimbangkan untuk membuat HTML ke dalam halaman di dalam wadah tersembunyi, kemudian memperbaruinya dan membuatnya terlihat saat dibutuhkan. Dengan cara ini, sebagian besar markup Anda dapat dipra-parsing oleh browser dan menghindari macet oleh JavaScript saat dipanggil. Semoga ini membantu!

Collin Allen
sumber
Terima kasih atas sarannya. Saya telah menggunakan pendekatan ini sebelumnya, namun dalam kasus khusus ini saya secara khusus ingin tahu tentang membuat elemen.
Darko Z
20

Ini bukan jawaban yang benar untuk pertanyaan itu tetapi saya tetap ingin membagikan ini ...

Menggunakan just document.createElement('div')and skipping JQuery akan banyak meningkatkan kinerja ketika Anda ingin membuat banyak elemen dengan cepat dan menambahkan ke DOM.

Irshad
sumber
16

Saya pikir Anda menggunakan metode terbaik, meskipun Anda bisa mengoptimalkannya untuk:

 $("<div/>");
tvanfosson
sumber
11

Anda tidak perlu kinerja mentah dari operasi yang akan Anda lakukan sangat jarang dari sudut pandang CPU.

yfeldblum
sumber
Tergantung pada seberapa sering Anda melakukannya.
Rich Bradshaw
8
OP sedang membuat popup modal . Operasi ini tidak diulang ribuan kali per detik. Sebaliknya, itu diulangi mungkin sekali setiap beberapa detik, maksimal. Menggunakan jQuery(html :: String)metode ini baik-baik saja. Kecuali situasi yang sangat tidak biasa, salah satu akan tidak mungkin untuk mencapai yang lebih baik dirasakan kinerja. Habiskan energi optimisasi pada kasing yang dapat menggunakannya. Selain itu, jQuery dioptimalkan untuk kecepatan dalam banyak hal. Lakukan hal-hal yang waras dengan itu, dan percaya-tetapi-verifikasi untuk menjadi cepat.
yfeldblum
9

Anda harus memahami bahwa pentingnya kinerja pembuatan elemen tidak relevan dalam konteks menggunakan jQuery.

Ingat, tidak ada tujuan nyata untuk membuat elemen kecuali Anda benar-benar akan menggunakannya.

Anda mungkin tergoda untuk menguji kinerja sesuatu seperti $(document.createElement('div'))vs. $('<div>')dan mendapatkan keuntungan kinerja yang hebat dari menggunakan $(document.createElement('div'))tetapi itu hanya elemen yang belum ada dalam DOM.

Namun, pada akhirnya, Anda tetap ingin menggunakan elemen tersebut sehingga tes sesungguhnya harus mencakup f.ex. .appendTo ();

Mari kita lihat, jika Anda menguji yang berikut terhadap satu sama lain:

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

Anda akan melihat hasilnya akan bervariasi. Terkadang satu cara lebih baik kinerjanya daripada yang lain. Dan ini hanya karena jumlah tugas latar belakang di komputer Anda berubah seiring waktu.

Uji diri Anda di sini

Jadi, pada akhirnya, Anda ingin memilih cara terkecil dan paling mudah dibaca untuk membuat elemen. Dengan begitu, setidaknya, file skrip Anda akan sekecil mungkin. Mungkin faktor yang lebih signifikan pada titik kinerja daripada cara membuat elemen sebelum Anda menggunakannya di DOM.

Jani Hyytiäinen
sumber
Saya tahu ini sudah tua, tetapi tidak perlu untuk jQuery dalam contoh pertama:document.getElementById('target).appendChild(document.createElement('div'));
hisdrewness
7

Satu hal yang lebih mudah dilakukan:

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

Kemudian untuk melakukan semua itu dengan panggilan jquery.

Tobiah
sumber
3

Saya menggunakan jquery.min v2.0.3. Bagi saya lebih baik menggunakan yang berikut:

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

sebagai berikut:

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

Waktu pemrosesan kode pertama jauh lebih rendah daripada kode kedua.

Marcel GJS
sumber