Kesalahan Javascript umum yang sangat memengaruhi kinerja? [Tutup]

10

Pada pertemuan UI / UX baru-baru ini yang saya hadiri, saya memberikan umpan balik pada situs web yang menggunakan Javascript (jQuery) untuk interaksi dan UI-nya - itu adalah animasi dan manipulasi yang cukup sederhana, tetapi kinerja pada komputer yang layak mengerikan.

Ini benar-benar mengingatkan saya pada banyak situs / program yang pernah saya lihat dengan masalah yang sama, di mana tindakan tertentu benar-benar menghancurkan kinerja. Ini sebagian besar dalam (atau setidaknya lebih terlihat dalam) situasi di mana Javascript hampir berfungsi sebagai pengganti Flash. Ini sangat kontras dengan beberapa aplikasi web yang saya gunakan yang memiliki lebih banyak Javascript dan fungsionalitas tetapi berjalan sangat lancar (COGNOS oleh IBM adalah salah satu yang dapat saya pikirkan dari atas kepala saya).

Saya ingin mengetahui beberapa masalah umum yang tidak dipertimbangkan saat mengembangkan JS yang akan mematikan kinerja situs.

Nic
sumber
Kemungkinan sama dengan setiap program lainnya: Melakukan lebih banyak pekerjaan daripada yang diperlukan dan melakukan pekerjaan yang sama berulang kali, seringkali ratusan kali.
1
@delnan itu sangat benar, tetapi sepertinya itu jauh lebih lazim di JS. Persepsi mungkin?
Nic
1
Sudah agak ketinggalan zaman untuk berbicara tentang 'situs' ketika berbicara tentang JavaScript. Itu ada di mana-mana dan digunakan untuk semuanya akhir-akhir ini.
Adam Crossland
@Adam Crossland Anda benar sekali - dalam contoh yang sama saya pikir saya membantu pengembang dengan aplikasi asli yang sangat bergantung pada jQuery juga.
Nic
1
Bukan jawaban yang tepat untuk pertanyaan Anda, jadi saya berkomentar: Saya telah mengalami situasi di mana JavaScript melakukan banyak render, dan itu sebenarnya adalah mesin rendering browser yang menghabiskan detik. Oleh karena itu, untuk menangani bottleneck kinerja, saya akan mencari operasi rendering yang tidak perlu terlebih dahulu.
user281377

Jawaban:

8

Seorang pembunuh kinerja umum memanggil .lengthHTMLCollection di dalam forloop:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

Anti-pola itu menyebabkan ukuran koleksi dihitung pada setiap melewati loop. Pendekatan yang lebih baik adalah menghitung panjang di luar loop:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}
Adam Crossland
sumber
3
Tergantung pada browser. Ambil patokan ini sebagai contoh: Dalam FF 5, yang "normal" berjalan dalam waktu yang hampir bersamaan dengan versi "yang dioptimalkan". Dan bahkan di browser yang sangat tua dan lamban, sesuatu seperti ini kemungkinan tidak akan menjadi hambatan jika JS benar-benar melakukan sesuatu yang menarik dengan elemen tersebut.
1
Hmm! Mungkin kompiler JIT yang sangat optimal saat ini membuat sedikit kebijaksanaan ini menjadi usang.
Adam Crossland
4
Saya bukan ahli nyata di sini, tetapi dari spec ECMA tampak bahwa panjang hanya properti objek array. Jadi menyebutnya hanya mengembalikan nilai alih-alih menghitung semua elemen. Tidak tahu apakah semua implementasi mengikuti spesifikasi, tetapi jika ya, kode Anda tidak meningkatkan kinerja sama sekali.
Jacek Prucia
4
@ JacekPrucia Katanya koleksi , bukan array - biasanya, dalam kode nyata, ini berarti daftar elemen DOM yang dikembalikan oleh fungsi seperti document.getElementsByTagName. Fungsi mengembalikan live nodeListyang menghitung ulang panjangnya setiap kali .lengthproperti diakses.
Yi Jiang
2
Benchmark @ JacekPrucia adalah peningkatan kinerja. Pencarian properti tidak murah.
Raynos
4

Tidak, masalahnya bukan berasal dari JS yang digunakan sebagai pengganti flash. Jika Anda tidak yakin dengan hal itu, dokumentasikan diri Anda tentang skrip tindakan: sangat dekat dengan JS.

Sebagai pembunuh kinerja, Anda dapat menemukan beberapa praktik buruk:

  • Lampirkan event handler pada acara yang terus-menerus, seperti menggulir, merapikan mouse atau hal serupa. Ini memiliki 2 kelemahan: jika acara tidak cukup dipicu, aplikasi Anda tidak akan reaktif. Jika dipicu terlalu banyak, Anda akan memiliki beban CPU yang sangat besar tanpa biaya.
  • Melakukan panggilan AJAX yang sinkron. Javascript tidak multithreaded, maka, ketika sebagian JS sedang menunggu sesuatu, aplikasi Anda dibekukan. Anda lebih baik menggunakan panggilan AJAX asinkron, dan cara yang sama menggunakan setTimeout / setInterval untuk membagi fase perhitungan yang panjang dan menjaga aplikasi Anda reaktif.
  • Kompleksitas algoritme tinggi seperti dalam bahasa lain.
deadalnix
sumber
Saya telah melihat lebih dari beberapa aplikasi mencoba memutar, mempermudah, atau menghidupkan gambar peramban penuh dan gagal total dalam prosesnya - di situlah komentar pengganti Flash berasal dari :)
Nic
Karena A pertama di AJAX berarti asinkron, secara teknis itu bukan AJAX jika sinkron, tetapi poin Anda masih bagus.
Karl Bielefeldt
Ya benar, itu tidak sepenuhnya AJAX. Tapi bagaimanapun, ini harus dihindari: D
deadalnix
3

Saya memberikan umpan balik pada situs web yang menggunakan Javascript (jQuery) untuk interaksinya dan UI - itu adalah animasi dan manipulasi yang cukup sederhana, tetapi kinerja pada komputer yang layak mengerikan.

Masalah terbesar dengan kinerja adalah menggunakan abstraksi tingkat tinggi (seperti jQuery) tanpa memahami model DOM yang mendasari dan model animasi CSS3 (atau kanvas, atau svg).

Jika Anda tidak tahu bagaimana melakukannya tanpa abstraksi maka Anda memiliki pengetahuan nol mutlak tentang teknik apa yang cepat atau lambat.

Pelajari JavaScript, Pelajari DOM. Setelah Anda mengetahui keduanya dan Anda tahu apa yang dilakukan abstraksi di bawah tenda, maka Anda dapat menggunakannya secara efisien. Tentu saja sebagian besar waktu Anda menyadari abstraksi lambat dan lakukan secara manual tanpa perpustakaan.

Raynos
sumber
1

Keindahan dan kelemahan Javascript adalah sangat fleksibel. Yang sedang berkata, itu sebenarnya memungkinkan Anda untuk melakukan hal-hal yang mungkin tidak boleh Anda lakukan dalam banyak kasus.

Dari ulasan kode yang saya ikuti, kekhawatiran utama cenderung terkait dengan rendering CSS. Untuk pengembang JS yang lebih baru, kami cenderung melihat terlalu banyak variabel yang digunakan dalam lingkup global.

Juga, penutupan yang tidak tepat sering dapat menyebabkan kebocoran memori. Namun, sebagian besar kerangka kerja Javascript modern mencegah masalah seperti ini selama kode Anda mengikuti kerangka tersebut.

Menggerutu
sumber
0

Berikut ini adalah tautan cepat yang saya temukan sekitar setahun lalu tentang penulisan kode jquery yang lebih baik: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

Satu hal yang saya temukan dalam kode rekan kerja yang mematikan kinerja adalah caching data yang tidak perlu di-cache.

Contoh:

var table = $("#data").dataTable(.....);

DataTables adalah plug-in jQuery yang kami gunakan untuk membuat kisi yang bagus. Bagaimanapun, tabel memiliki hampir 5k baris di dalamnya, menerapkan plug-in DataTables dan kemudian menyimpannya dalam variabel tabel sebenarnya menyebabkan FireFox dan IE untuk memperingatkan bahwa skrip terlalu lama. Moral dari cerita, hanya cache data jika Anda perlu.

Tyanna
sumber
1
Kedengarannya seperti DataTable menjadi plugin yang benar-benar tidak efisien / buruk daripada masalah dengan caching. 5k bukan apa-apa.
Raynos
@ Raynos: Dia mengatakan 5k baris , bukan 5 kilobyte data. "Baris" bisa menjadi hal yang sangat besar.
Chris Farmer
@ ChrisFarmer Jika "baris" adalah hal yang sangat besar maka Anda punya masalah yang berbeda .
Raynos
-1

Dari apa yang saya dengar forloop secara komputasi lebih cepat daripada jQuery $.each().

tesis
sumber
3
Apakah ini lelucon?
Raynos