Rumah > Artikel > hujung hadapan web > Beberapa cadangan pengoptimuman untuk jQuery performance_jquery
Jangan akses sifat panjang tatasusunan setiap kali dalam gelung, cachekannya sebelum gelung bermula:
var myLength = myArray.length; for (var i = 0; i < myLength; i++) { // do stuff }
Lakukan operasi tambah di luar gelung
Manipulasi langsung DOM sangat intensif prestasi, terutamanya jangan memanipulasi DOM secara langsung dalam gelung:
// 这样性能很差 $.each(myArray, function(i, item) { var newListItem = '<li>' + item + '</li>'; $('#ballers').append(newListItem); }); <p>// 这样性能较好<br />var frag = document.createDocumentFragment();</p><p>$.each(myArray, function(i, item) {<br /> var newListItem = '<li>' + item + '</li>';<br /> frag.appendChild(newListItem);<br />});<br />$('#ballers')[0].appendChild(frag);</p><p>// 这样也很好<br />var myHtml = '';</p><p>$.each(myArray, function(i, item) {<br /> html += '<li>' + item + '</li>';<br />});<br />$('#ballers').html(myHtml);</p>
Pastikan kod padat
Elakkan melakukan perkara yang berulang. Jika anda terus melakukan perkara yang sama, ada sesuatu yang tidak kena:
// 丑 if ($eventfade.data('currently') != 'showing') { $eventfade.stop(); } if ($eventhover.data('currently') != 'showing') { $eventhover.stop(); } if ($spans.data('currently') != 'showing') { $spans.stop(); } // 漂亮!! var $elems = [$eventfade, $eventhover, $spans]; $.each($elems, function(i,elem) { if (elem.data('currently') != 'showing') { elem.stop(); } });
Berhati-hati dengan fungsi tanpa nama
Sangat menyakitkan untuk mempunyai fungsi tanpa nama yang terbang ke seluruh tempat. Ia sukar untuk nyahpepijat, menyelenggara, menguji atau menggunakan semula Anda harus menamakan fungsi tersebut sebanyak mungkin dan merangkumnya dalam objek untuk melaksanakan pengurusan yang berkesan. >
// 不好 $(document).ready(function() { $('#magic').click(function(e) { $('#yayeffects').slideUp(function() { // ... }); }); $('#happiness').load(url + ' #unicorns', function() { // ... }); }); // 好 var PI = { onReady : function() { $('#magic').click(PI.candyMtn); $('#happiness').load(PI.url + ' #unicorns', PI.unicornCb); }, candyMtn : function(e) { $('#yayeffects').slideUp(PI.slideCb); }, slideCb : function() { ... }, unicornCb : function() { ... } }; $(document).ready(PI.onReady);
Pengoptimuman pemilih
Memandangkan semakin ramai pelayar menyokong document.querySelectorAll(), beban pemilih perlahan-lahan dipindahkan ke penyemak imbas, tetapi masih terdapat beberapa petua untuk diberi perhatian:Utamakan dan gunakan pemilih ID apabila boleh:
// 快 $('#container div.robotarm'); // 相当快 $('#container').find('div.robotarm'); 使用 $.fn.find 的方式更快,因为在 $.fn.find 之前的选择器并没有使用 jQuery 自带的 Sizzle 选择器引擎,而是使用了浏览器 document.getElementById() 方法,浏览器原生的方法自然更快。 使用组合选择器时,尽可能使右端更明确,而左端不尽量不明确: // 未优化 $('div.data .gonzalez'); // 已优化 $('.data td.gonzalez');
Elakkan terlalu spesifik:
$('.data table.attendees td.gonzalez'); // 在不影响结果的情况下尽量删掉中间多余部分 $('.data td.gonzalez');
Cuba elakkan menggunakan kad bebas Sebarang penggunaan kad bebas secara eksplisit atau tersirat akan mengurangkan prestasi pemilih:
$('.buttons > *'); // 极慢 $('.buttons').children(); // 好多了 $('.gender :radio'); // 隐式地使用通配符,慢 $('.gender *:radio'); // 显式地使用通配符,同上,慢 $('.gender input:radio'); // 嗯,快多了
Gunakan proksi acara
Proksi acara membenarkan acara diikat pada bekas (seperti senarai ul tidak tersusun), dan bukannya kepada semua elemen dalam bekas (seperti elemen senarai li). Walaupun $.fn.live dan $.fn.delegate kedua-duanya mengikat acara pada bekas, $.fn.delegate harus digunakan sebaik mungkin, bagaimanapun, konteksnya yang jelas (berbanding dengan konteks $.fn.live document ) adalah jauh lebih kecil, mengelakkan banyak penapisan yang tidak perlu.Selain peningkatan prestasi, jika anda menambah elemen baharu pada bekas yang terikat pada acara, elemen baharu ini tidak perlu terikat pada acara itu lagi, yang juga merupakan kelebihan.
// 不好 (如果列表元素非常多,你就悲剧了) $('li.trigger').click(handlerFn); // 好些:使用 $.fn.live 进行事件代理 $('li.trigger').live('click', handlerFn); // 最好:使用 $.fn.delegate 进行事件代理 // 因为这样可以明确的指定一个上下文 $('#myList').delegate('li.trigger', 'click', handlerFn);
Putuskan elemen daripada DOM dan kemudian kendalikannya
Operasi DOM agak perlahan, jadi anda harus cuba mengelak daripada mengendalikan DOM secara langsung. jQuery memperkenalkan kaedah $.fn.detach dalam versi 1.4, yang boleh memunggah elemen daripada DOM dan kemudian mengendalikannya Selepas operasi selesai, ia boleh ditambahkan pada DOM:
var $table = $('#myTable'); var $parent = $table.parent(); $table.detach(); // ... 例如这里给表格添加了很多很多行 $parent.append(table);
Gunakan helaian gaya luaran untuk mengubah suai gaya bagi sejumlah besar elemen
Apabila menggunakan $.fn.css untuk mengubah suai gaya untuk lebih daripada 20 elemen, anda harus mempertimbangkan untuk menambah teg gaya terus ke halaman, yang dikatakan meningkatkan prestasi sebanyak 60%.
// 当元素少于 20 个时使用这个方法,多余 20 个时,速度就慢了 $('a.swedberg').css('color', '#asd123'); // 多余 20 个元素时,应考虑直接在页面中添加 style 标签 $('<style type="text/css">a.swedberg { color : #asd123 }</style>') .appendTo('head');
Gunakan $.data dan bukannya $.fn.data
Memohon $.data pada elemen DOM adalah 10 kali lebih pantas daripada memanggil $.fn.data terus pada pemilih. Sudah tentu, premisnya adalah untuk terlebih dahulu memahami perbezaan antara elemen DOM dan set hasil jQuery.
// 速度一般 $(elem).data(key,value); // 速度提升 10 倍 $.data(elem,key,value);
Jangan buang masa dengan elemen kosong
jQuery tidak akan memberitahu anda secara aktif bahawa anda menjalankan kod pada set hasil kosong – dan tiada ralat akan berlaku semasa pelaksanaan. Jadi kadangkala sebelum melaksanakan kod, anda perlu terlebih dahulu menentukan sama ada set hasil kosong:
// 不好:执行了三个函数之后 // 才发现结果集上没有任何元素 $('#nosuchthing').slideUp(); // 好 var $mySelection = $('#nosuchthing'); if ($mySelection.length) { $mySelection.slideUp(); } // 最好:增加一个 doOnce 插件 jQuery.fn.doOnce = function(func){ this.length && func.apply(this); return this; } $('li.cartitems').doOnce(function(){ // 这里可以确保结果集不是空的 });
Takrif pembolehubah
// 老掉牙的写法 var test = 1; var test2 = function() { ... }; var test3 = test2(test); // 新写法 var test = 1, test2 = function() { ... }, test3 = test2(test);
(function(foo, bar) { ... })(1, 2);
Penghakiman bersyarat
// 土方法 if (type == 'foo' || type == 'bar') { ... } // 较先进的方法 if (/^(foo|bar)$/.test(type)) { ... } // 使用对象查找 if (({ foo : 1, bar : 1 })[type]) { ... }