jQuery vs document.querySelectorAll

161

Saya mendengar beberapa kali bahwa aset terkuat jQuery adalah cara ia menanyakan dan memanipulasi elemen dalam DOM: Anda dapat menggunakan kueri CSS untuk membuat kueri kompleks yang akan sangat sulit dilakukan dalam javascript biasa. Namun, sejauh yang saya tahu, Anda dapat mencapai hasil yang sama dengan document.querySelectoratau document.querySelectorAll, yang didukung di Internet Explorer 8 ke atas.

Jadi pertanyaannya adalah ini: mengapa 'risiko' overhead jQuery jika aset terkuatnya dapat dicapai dengan JavaScript murni?

Saya tahu jQuery memiliki lebih dari sekedar penyeleksi CSS, misalnya browser lintas AJAX, acara yang bagus, dll. Tetapi bagian permintaannya adalah bagian yang sangat besar dari kekuatan jQuery!

Adakah pikiran?

Joel_Blum
sumber
4
(1) Traversal / modifikasi DOM jauh lebih cepat dan lebih mudah dengan jQuery. (2) Ia menambahkan pemilih sendiri yang tidak akan berfungsi dalam querySelectormetode. (3) Melakukan panggilan AJAX jauh lebih cepat dan lebih mudah dengan jQuery. (4) Dukungan di IE6 +. Saya yakin ada banyak poin yang bisa dibuat juga.
James Allardice
12
(5) ... singkatan $ () untuk juru ketik malas adalah suatu keharusan.
Dexter Huinda
4
lebih mudah ya, mengapa lebih cepat? jQuery diterjemahkan menjadi javascript biasa sejauh yang saya tahu ...
Joel_Blum
4
@ JamesAllardice— "semua kekacauan itu" untuk lintas-browser XMLHttpRequest mungkin 30 baris kode yang Anda tulis sekali dan masukkan ke perpustakaan Anda sendiri.
RobG
6
@RobG - Ya, saya tidak mengatakan hanya menggunakan jQuery jika hanya itu yang Anda coba gunakan. Itu hanya salah satu manfaatnya. Jika Anda memerlukan traversal DOM yang mudah, AJAX dan querySelectorAll, dan Anda membutuhkan semuanya untuk bekerja di browser lama, maka jQuery adalah pilihan yang jelas. Saya tidak mengatakan bahwa Anda harus menggunakannya seperti ini .
James Allardice

Jawaban:

127

document.querySelectorAll() memiliki beberapa ketidakkonsistenan di seluruh browser dan tidak didukung di browser yang lebih lama. Hal ini mungkin tidak akan menimbulkan masalah lagi saat ini . Ini memiliki mekanisme pelingkupan yang sangat tidak intuitif dan beberapa fitur lain yang tidak begitu bagus . Juga dengan javascript Anda mengalami kesulitan bekerja dengan set hasil dari kueri ini, yang dalam banyak kasus mungkin ingin Anda lakukan. jQuery menyediakan fungsi untuk bekerja pada mereka seperti: filter(), find(), children(), parent(), map(), not()dan beberapa lagi. Belum lagi kemampuan jQuery untuk bekerja dengan penyeleksi pseudo-class.

Namun, saya tidak akan menganggap hal-hal ini sebagai fitur terkuat jQuery tetapi hal-hal lain seperti "bekerja" pada dom (acara, gaya, animasi & manipulasi) dengan cara yang kompatibel dengan crossbrowser atau antarmuka ajax.

Jika Anda hanya menginginkan mesin pemilih dari jQuery, Anda dapat menggunakan satu mesin pemilih jQuery sendiri: Sizzle Dengan begitu Anda memiliki kekuatan mesin pemilih Selector jQuerys tanpa overhead yang buruk.

EDIT: Sekadar catatan, saya penggemar berat vanilla JavaScript. Namun itu fakta bahwa Anda kadang-kadang membutuhkan 10 baris JavaScript di mana Anda akan menulis 1 baris jQuery.

Tentu saja Anda harus disiplin untuk tidak menulis jQuery seperti ini:

$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green').end();

Ini sangat sulit dibaca, sedangkan yang terakhir cukup jelas:

$('ul.first')
   .find('.foo')
      .css('background-color', 'red')
.end()
   .find('.bar')
      .css('background-color', 'green')
.end();

JavaScript yang setara akan jauh lebih kompleks diilustrasikan oleh kodesemu di atas:

1) Temukan elemen, pertimbangkan untuk mengambil semua elemen atau hanya elemen pertama.

// $('ul.first')
// taking querySelectorAll has to be considered
var e = document.querySelector("ul.first");

2) Iterate melalui array node anak melalui beberapa loop (mungkin bersarang atau rekursif) dan periksa kelas (daftar kelas tidak tersedia di semua browser!)

//.find('.foo')
for (var i = 0;i<e.length;i++){
     // older browser don't have element.classList -> even more complex
     e[i].children.classList.contains('foo');
     // do some more magic stuff here
}

3) menerapkan gaya css

// .css('background-color', 'green')
// note different notation
element.style.backgroundColor = "green" // or
element.style["background-color"] = "green"

Kode ini setidaknya dua kali lebih banyak baris kode yang Anda tulis dengan jQuery. Anda juga harus mempertimbangkan masalah lintas-browser yang akan membahayakan keunggulan kecepatan yang parah (selain dari keandalan) dari kode asli.

Christoph
sumber
33
Inkonsistensi macam apa yang querySelectorAllada di antara browser? Dan bagaimana menggunakan jQuery menyelesaikan ini, karena jQuery menggunakan querySelectorAll saat tersedia?
3
Benar, satu baris kode dapat berisi rantai kode tanpa akhir yang bisa sangat mengganggu selama proses debug.
Dexter Huinda
1
"2) iterate melalui array childnodes melalui beberapa (mungkin bersarang atau rekursif) loop dan periksa kelas" << Ini adalah omong kosong total. Anda bisa menggunakan querySelectorAll pada elemen di langkah sebelumnya.
Vanuan
5
@Vanuan ini mungkin tidak perlu, tetapi jika Anda akan membaca jawaban saya dengan saksama, Anda akan memperhatikan, bahwa querySelector memiliki masalah pelingkupan yang serius yang mungkin memberi Anda banyak kesalahan positif ketika digunakan dengan cara yang Anda usulkan. Meskipun demikian, saat Anda bebas untuk naik atau turun karena alasan yang tidak masuk akal, saya pikir itu bukan alasan untuk menggunakan bahasa kasar.
Christoph
2
@Christoph Karena ini mudah, saya menambahkan kompatibilitas untuk IE8 dan di atasnya. Keunggulan kecepatan masih besar (5-20 kali). Bahwa kode akan berjalan lebih lambat di browser lama seperti IE8 hanyalah asumsi yang salah.
Pascalius
60

Jika Anda mengoptimalkan halaman Anda untuk IE8 atau yang lebih baru, Anda harus benar-benar mempertimbangkan apakah Anda memerlukan jquery atau tidak. Browser modern memiliki banyak aset yang disediakan oleh jquery.

Jika Anda peduli dengan kinerja, Anda dapat memperoleh manfaat kinerja luar biasa (2-10 lebih cepat) menggunakan javascript asli: http://jsperf.com/jquery-vs-native-selector-and-element-style/2

Saya mengubah div-tagcloud dari jquery ke javascript asli (kompatibel IE8 +), hasilnya mengesankan. 4 kali lebih cepat dengan hanya sedikit overhead.

                    Number of lines       Execution Time                       
Jquery version :        340                    155ms
Native version :        370                    27ms

You Might Not Need Jquery menyediakan ikhtisar yang sangat bagus, yang diganti metode asli untuk versi peramban mana.

http://youmightnotneedjquery.com/


Lampiran: Perbandingan kecepatan lebih lanjut bagaimana metode asli bersaing dengan jquery

Pascalius
sumber
ikhtisar yang bagus meskipun beberapa contoh kode salah ... Misalnya $(el).find(selector)tidak sama dengan el.querySelectorAll(selector)dan kinerja metode asli seringkali cukup mengerikan: stackoverflow.com/q/14647470/1047823
Christoph
@Christoph Bisakah Anda menguraikan, mengapa Anda berpikir metode ini berbeda? Tentu saja ada kasus tepi di mana jquery dapat berkinerja lebih baik, tetapi saya belum melihat satu pun untuk manipulasi DOM.
Pascalius
1
Tidak perlu dijabarkan lebih lanjut, baca saja jawaban saya, lihat biola dan artikel yang saya tautkan. Juga, (setidaknya atm) sebagian besar metode Array asli lebih rendah dalam kecepatan dibandingkan dengan implementasi js naif (seperti saya ditautkan dalam pertanyaan dalam komentar pertama saya). Dan ini bukan kasus tepi, melainkan kasus standar. Tetapi sekali lagi, fokus utama dari pertanyaan ini bukanlah kecepatan.
Christoph
2
@Christoph Tentu saja, metode ini tidak 100% sama dan jquery sering memberikan kenyamanan lebih. Saya memperbarui jawaban untuk menunjukkan bahwa ini hanya kasus tepi, saya benar-benar tidak dapat menemukan kasus lain di mana jquery berkinerja lebih baik. Tidak ada fokus utama dari pertanyaan ini.
Pascalius
+1 Jawaban luar biasa! Saya perlahan-lahan mengganti kode jQuery lama dengan JavaScript mentah selama 4 atau 5 tahun terakhir di mana pun dan kapan pun memungkinkan. Tentu saja, jQuery bagus untuk beberapa hal dan saya menggunakannya untuk hal - hal itu ketika saya merasa mendapatkan manfaat yang kuat.
Ya Barry
13

Untuk memahami mengapa jQuery begitu populer, penting untuk memahami dari mana kita berasal!

Sekitar satu dekade yang lalu, browser teratas adalah IE6, Netscape 8 dan Firefox 1.5. Kembali pada masa itu, ada sedikit cara lintas browser untuk memilih elemen dari DOM Document.getElementById().

Jadi, ketika jQuery dirilis kembali pada tahun 2006 , itu cukup revolusioner. Saat itu, jQuery menetapkan standar untuk cara memilih / mengubah elemen HTML dengan mudah dan memicu acara, karena fleksibilitas dan dukungan browsernya belum pernah terjadi sebelumnya.

Sekarang, lebih dari satu dekade kemudian, banyak fitur yang membuat jQuery begitu populer telah dimasukkan dalam standar javaScript:

Ini umumnya tidak tersedia kembali pada tahun 2005. Fakta bahwa mereka hari ini jelas menimbulkan pertanyaan mengapa kita harus menggunakan jQuery sama sekali. Dan memang, orang semakin bertanya-tanya apakah kita harus menggunakan jQuery sama sekali .

Jadi, jika Anda pikir Anda memahami JavaScript cukup baik untuk dilakukan tanpa jQuery, silakan lakukan! Jangan merasa terpaksa menggunakan jQuery, hanya karena begitu banyak orang lain yang melakukannya!

John Slegers
sumber
7

Itu karena jQuery dapat melakukan lebih dari itu querySelectorAll.

Pertama-tama, jQuery (dan Sizzle, khususnya), berfungsi untuk peramban lama seperti IE7-8 yang tidak mendukung pemilih CSS2.1-3.

Plus, Sizzle (yang merupakan mesin pemilih di belakang jQuery) menawarkan banyak instrumen pemilih yang lebih canggih, seperti :selectedpseudo-class, :not()pemilih lanjutan , sintaksis yang lebih kompleks seperti di $("> .children")dan sebagainya.

Dan ia melakukannya lintas-browser, tanpa cacat, menawarkan semua yang dapat ditawarkan jQuery (plugin dan API).

Ya, jika Anda pikir Anda bisa mengandalkan penyeleksi kelas dan id sederhana, jQuery terlalu banyak untuk Anda, dan Anda akan membayar lunas yang berlebihan. Tetapi jika Anda tidak, dan ingin memanfaatkan semua kebaikan jQuery, maka gunakan.

MaxArt
sumber
7

Mesin pemilih Sizzle jQuery dapat digunakan querySelectorAlljika tersedia. Ini juga memuluskan inkonsistensi antar browser untuk mencapai hasil yang seragam. Jika Anda tidak ingin menggunakan semua jQuery, Anda bisa menggunakan Sizzle secara terpisah. Ini adalah roda yang cukup mendasar untuk diciptakan.

Berikut ini beberapa pilihan sakura dari sumber yang menunjukkan jenis-jenis barang seperti jQuery (dengan Sizzle):

Mode kebiasaan quirks:

if ( document.querySelectorAll ) {
  (function(){
    var oldSizzle = Sizzle,
      div = document.createElement("div"),
      id = "__sizzle__";

    div.innerHTML = "<p class='TEST'></p>";

    // Safari can't handle uppercase or unicode characters when
    // in quirks mode.
    if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
      return;
    }

Jika penjaga itu gagal itu menggunakan itu adalah versi Sizzle yang tidak ditingkatkan dengan querySelectorAll. Lebih jauh ke bawah ada pegangan khusus untuk inkonsistensi di IE, Opera, dan browser Blackberry.

  // Check parentNode to catch when Blackberry 4.6 returns
  // nodes that are no longer in the document #6963
  if ( elem && elem.parentNode ) {
    // Handle the case where IE and Opera return items
    // by name instead of ID
    if ( elem.id === match[3] ) {
      return makeArray( [ elem ], extra );
    }

  } else {
    return makeArray( [], extra );
  }

Dan jika semuanya gagal itu akan mengembalikan hasil oldSizzle(query, context, extra, seed).

KGZM
sumber
6

Dalam hal pemeliharaan kode, ada beberapa alasan untuk tetap menggunakan perpustakaan yang banyak digunakan.

Salah satu yang utama adalah bahwa mereka didokumentasikan dengan baik, dan memiliki komunitas seperti ... katakanlah ... stackexchange, di mana bantuan dengan perpustakaan dapat ditemukan. Dengan pustaka kode khusus, Anda memiliki kode sumber, dan mungkin dokumen bagaimana caranya, kecuali jika pembuat kode menghabiskan lebih banyak waktu untuk mendokumentasikan kode daripada menulisnya, yang sangat jarang.

Menulis pustaka Anda sendiri mungkin cocok untuk Anda , tetapi siswa magang yang duduk di meja sebelah mungkin memiliki waktu lebih mudah untuk mempercepat dengan sesuatu seperti jQuery.

Sebut saja efek jaringan jika Anda mau. Ini bukan untuk mengatakan bahwa kode akan lebih unggul di jQuery; Hanya saja sifat singkat dari kode membuatnya lebih mudah untuk memahami struktur keseluruhan untuk programmer dari semua tingkat keahlian, jika hanya karena ada lebih banyak kode fungsional yang terlihat sekaligus dalam file yang Anda lihat. Dalam hal ini, 5 baris kode lebih baik dari 10.

Singkatnya, saya melihat manfaat utama jQuery sebagai kode ringkas, dan di mana-mana.

Hari Dom
sumber
6

Berikut ini perbandingan jika saya ingin menerapkan atribut yang sama, misalnya menyembunyikan semua elemen kelas "kelas saya". Ini adalah salah satu alasan untuk menggunakan jQuery.

jQuery:

$('.my-class').hide();

JavaScript:

var cls = document.querySelectorAll('.my-class');
for (var i = 0; i < cls.length; i++) {
    cls[i].style.display = 'none';
}

Dengan jQuery yang sudah sangat populer, mereka seharusnya membuat document.querySelector () berperilaku seperti $ (). Alih-alih, document.querySelector () hanya memilih elemen pencocokan pertama yang membuatnya hanya berguna setengah jalan.

Steven
sumber
4
Saya akan melakukan. ForEach di sini.
Phillip Senn
Yah Anda selalu bisa pergi dengan rute yang lebih mudah document.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');. Meski pun lebih pendek, performa asli yang bijaksana selalu lebih baik.
Alain Cruz
Dari sudut pandang pengguna, semua yang terjadi dalam waktu kurang dari 0,1 detik, segera terjadi. Oleh karena itu asli bahkan lebih cepat, lebih baik hanya jika implementasi jQuery lebih lambat dari 0,1 detik. Dan dalam aplikasi dunia nyata tidak pernah demikian.
yurin
3

seperti situs resmi mengatakan: "jQuery: Perpustakaan Tulis Kurang, Lakukan Lebih Banyak,"

coba terjemahkan kode jQuery berikut tanpa pustaka

$("p.neat").addClass("ohmy").show("slow");
simon xu
sumber
1
Saya setuju dengan itu, namun bagaimana dengan keterbacaan? bagaimana Anda bisa mendokumentasikan baris-baris kode yang panjang dengan banyak hal yang tidak terkait terjadi? Bagaimana Anda bisa men-debug monstrositas seperti itu?
Joel_Blum
@ user1032663 itu masalah dokumentasi-konvensi.
Christoph
1
Alternatif untuk jQuery (atau pustaka "populer" apa pun yang Anda pilih) bukan dengan menulis semuanya dari awal, tetapi menggunakan pustaka yang sesuai dengan tujuan Anda dan ditulis dengan baik. Anda mungkin telah menulis bagian sendiri, atau memilih perpustakaan modular seperti MyLibrary untuk memasukkan hanya apa yang Anda butuhkan.
RobG
2
Contoh yang Anda pilih tidak benar-benar membuktikan maksud Anda: Pertanyaannya adalah mencari perbedaan di provinsi "pemilih". addClass()dan show()tidak benar-benar masuk hitungan. Dan untuk $('p.neat'), Anda dapat melihat querySelector / All.
kumarharsh
document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));dan biarkan CSS melakukan sisanya. Kode sedikit lebih panjang, tetapi jauh lebih efisien. Tentu saja, solusinya tidak begitu tersedia di masa IE Legacy. Bagian “Do More” ironis. jQuery membutuhkan sekitar seratus baris kode untuk menemukan sesuatu, jadi melakukan lebih banyak tidak selalu produktif.
Manngo
2

Saya pikir jawaban sebenarnya adalah bahwa jQuery dikembangkan jauh sebelum querySelector/querySelectorAlltersedia di semua browser utama.

Rilis awal jQuery adalah pada tahun 2006 . Bahkan, bahkan jQuery bukan yang pertama yang menerapkan penyeleksi CSS .

IE adalah browser terakhir yang diimplementasikan querySelector/querySelectorAll. Versi 8 dirilis pada tahun 2009 .

Jadi sekarang, pemilih elemen DOM bukan lagi titik terkuat dari jQuery. Namun, ia masih memiliki banyak barang, seperti pintasan untuk mengubah konten css dan html elemen, animasi, event binding, ajax.

Vanuan
sumber
1

Pertanyaan lama, tetapi setengah dekade kemudian, perlu ditinjau kembali. Di sini saya hanya membahas aspek pemilih jQuery.

document.querySelector[All]didukung oleh semua browser saat ini, turun ke IE8, sehingga kompatibilitas tidak lagi menjadi masalah. Saya juga tidak menemukan masalah kinerja untuk dibicarakan (seharusnya lebih lambat daripada document.getElementById, tetapi pengujian saya sendiri menunjukkan bahwa itu sedikit lebih cepat).

Oleh karena itu ketika memanipulasi elemen secara langsung, itu lebih disukai daripada jQuery.

Sebagai contoh:

var element=document.querySelector('h1');
element.innerHTML='Hello';

adalah jauh lebih unggul untuk:

var $element=$('h1');
$element.html('hello');

Untuk melakukan apa saja, jQuery harus menjalankan melalui seratus baris kode (saya pernah menelusuri kode seperti di atas untuk melihat apa yang sebenarnya dilakukan jQuery dengannya). Ini jelas buang-buang waktu semua orang.

Biaya signifikan lain dari jQuery adalah kenyataan bahwa ia membungkus segala sesuatu di dalam objek jQuery baru. Overhead ini sangat boros jika Anda perlu membuka objek lagi atau menggunakan salah satu metode objek untuk menangani properti yang sudah terpapar pada elemen asli.

Di mana jQuery memiliki keuntungan, bagaimanapun, adalah bagaimana menangani koleksi. Jika persyaratannya adalah untuk mengatur properti beberapa elemen, jQuery memiliki eachmetode bawaan yang memungkinkan sesuatu seperti ini:

var $elements=$('h2');  //  multiple elements
$elements.html('hello');

Untuk melakukannya dengan Vanilla JavaScript akan membutuhkan sesuatu seperti ini:

var elements=document.querySelectorAll('h2');
elements.forEach(function(e) {
    e.innerHTML='Hello';
});

yang beberapa menemukan menakutkan.

Selektor jQuery juga sedikit berbeda, tetapi browser modern (tidak termasuk IE8) tidak akan mendapatkan banyak manfaat.

Sebagai aturan, saya memperingatkan agar tidak menggunakan jQuery untuk proyek baru :

  • jQuery adalah perpustakaan eksternal yang menambah overhead proyek, dan ketergantungan Anda pada pihak ketiga.
  • Fungsi jQuery sangat mahal, dari segi pemrosesan.
  • jQuery menerapkan metodologi yang perlu dipelajari dan dapat bersaing dengan aspek lain dari kode Anda.
  • jQuery lambat untuk mengekspos fitur baru dalam JavaScript.

Jika tidak ada hal di atas yang penting, maka lakukan apa yang Anda mau. Namun, jQuery tidak lagi penting untuk pengembangan lintas-platform seperti dulu, seperti JavaScript dan CSS modern berjalan lebih jauh dari sebelumnya.

Ini tidak menyebutkan fitur-fitur lain dari jQuery. Namun, saya pikir mereka juga perlu melihat lebih dekat.

Manngo
sumber
1
Sintaks Anda bahkan tidak benar untuk tidak menyebutkan hal-hal salah lainnya seperti "lambat untuk mengekspos fitur baru di Javascript" Pekerjaan JQuery bahkan tidak mengekspos fitur baru, itu untuk memudahkan Anda untuk memanipulasi DOM dan melakukan hal-hal sederhana yang bisa menjadi seperti 10 baris dalam Javascript. Seluruh komentar Anda tidak masuk akal dan memiliki banyak hal yang salah di dalamnya. Pertimbangkan untuk memperbaikinya.
Boy pro
@ Boypro Terima kasih atas komentar Anda, tetapi juga penuh dengan kesalahan. Mungkin Anda ingin berbagi tentang jawaban saya yang sangat menyinggung Anda. Apa yang "bahkan tidak benar". Lebih baik lagi, Anda mungkin ingin berkontribusi di server Anda sendiri. Pertanyaannya adalah tentang biaya penggunaan jQuery ketika JavaScript vanilla dapat melakukan banyak hal. Pertimbangkan untuk menjawabnya.
Manngo
0
$ ("# id") vs document.querySelectorAll ("# id")

Kesepakatannya adalah dengan fungsi $ () ia membuat sebuah array dan kemudian memecahnya untuk Anda tetapi dengan document.querySelectorAll () itu membuat sebuah array dan Anda harus memecahnya.


sumber
0

Hanya komentar tentang ini, ketika menggunakan lite desain material, pemilih jquery tidak mengembalikan properti untuk desain material karena beberapa alasan.

Untuk:

<div class="logonfield mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
        <input class="mdl-textfield__input" type="text" id="myinputfield" required>
        <label class="mdl-textfield__label" for="myinputfield">Enter something..</label>
      </div>

Ini bekerja:

document.querySelector('#myinputfield').parentNode.MaterialTextfield.change();

Ini tidak:

$('#myinputfield').parentNode.MaterialTextfield.change();
Ashvin Bhuttoo
sumber