Rumah >hujung hadapan web >tutorial js >Petua Pengoptimuman Prestasi JavaScript: Gambaran Keseluruhan
Sebelum kita menyelam ke dalam butiran, mari kita mula-mula memahami soalan ini dari perspektif makro yang lebih banyak: Apakah JavaScript berprestasi tinggi dan bagaimana ia sesuai dengan metrik prestasi web yang lebih luas?
mata utama
Tetapan latar belakang
Pertama sekali, kita perlu jelas: Jika anda hanya menguji desktop, anda tidak termasuk lebih daripada 50% pengguna.
Trend ini hanya akan terus berkembang apabila pengguna pasaran baru muncul mengakses Internet terutamanya melalui peranti Android yang berharga di bawah $ 100. Era desktop sebagai peranti utama untuk mengakses Internet telah berakhir, dan kumpulan seterusnya satu bilion pengguna Internet akan mengakses laman web anda terutamanya melalui peranti mudah alih.
Ujian dalam mod peranti dengan Chrome DevTools bukan pengganti ujian pada peranti sebenar. Menggunakan CPU dan rangkaian mengehadkan semasa membantu, tetapi ia pada dasarnya berbeza. Sila uji pada peranti sebenar.
Walaupun anda sedang menguji pada peranti mudah alih sebenar
, anda mungkin menguji dengan telefon utama $ 600 baru anda. Masalahnya ialah, ini bukan peranti pengguna anda. Peranti median adalah serupa dengan Moto G1 - peranti dengan memori kurang daripada 1GB, CPU dan GPU yang sangat lemah.mari kita lihat bagaimana ia berfungsi apabila parsing purata pakej JS.
addy osmani: masa purata untuk parsing dan penilaian JS.
oh tidak. Walaupun imej ini hanya meliputi masa parsing dan kompilasi JS (lebih banyak lagi pada kemudian) dan bukannya prestasi keseluruhan, ia berkait rapat dengan prestasi keseluruhan dan boleh digunakan sebagai metrik untuk prestasi JS keseluruhan.
memetik Bruce Lawson: "Ini adalah World Wide Web, bukan Web Barat yang kaya." Oleh itu, matlamat prestasi web anda adalah peranti kira -kira 25 kali lebih perlahan daripada MacBook atau iPhone anda. Fikirkan perkara ini dengan teliti. Tetapi ia lebih teruk lagi. Mari kita lihat apakah matlamat sebenar kita.
Apakah kod JS berprestasi tinggi?
Sekarang kita tahu platform sasaran, kita dapat menjawab soalan seterusnya: Apakah prestasi tinggi kod JS?
Walaupun tidak ada klasifikasi mutlak untuk menentukan kod berprestasi tinggi, kami mempunyai model prestasi yang berpusatkan pengguna yang boleh digunakan sebagai rujukan: model kereta api.
sam saccone: perancangan prestasi: prpl
Jika aplikasi anda bertindak balas terhadap tindakan pengguna dalam 100 milisaat, pengguna akan mempertimbangkan respons segera. Ini berfungsi untuk elemen yang boleh diklik, tetapi bukan untuk menatal atau menyeret.
Pada paparan 60Hz, kami ingin mencapai kadar bingkai malar sebanyak 60 bingkai sesaat semasa animasi dan menatal. Ini bermakna terdapat kira -kira 16 milisaat setiap bingkai. Dalam anggaran 16 milisaat ini, anda sebenarnya hanya mempunyai 8-10 milisaat untuk melakukan semua kerja, sepanjang masa diambil oleh mekanisme dalaman penyemak imbas dan perbezaan lain.
Jika anda mempunyai tugas yang mahal dan berterusan, pastikan untuk memisahkannya ke dalam ketulan yang lebih kecil supaya benang utama dapat bertindak balas terhadap input pengguna. Anda tidak sepatutnya mempunyai tugas yang menangguhkan input pengguna dengan lebih daripada 50 milisaat.
Anda harus mengawal masa pemuatan halaman hingga kurang dari 1000 milisaat. Selepas masa ini, pengguna anda akan mula merasa tidak sabar. Ini adalah matlamat yang agak sukar bagi halaman untuk menjadi interaktif, bukan hanya untuk menariknya pada skrin dan boleh ditatal. Malah, masa yang lebih pendek:
Cepat Secara lalai: Amalan Terbaik Memuatkan Moden (2017 Chrome Dev Summit)
Malah, matlamatnya adalah 5 saat masa interaksi. Ini adalah metrik yang digunakan Chrome dalam audit rumah api.
Oleh kerana kita tahu petunjuk, mari kita lihat beberapa statistik:
dan maklumat lanjut yang disediakan oleh Addy Osmani:
Adakah anda merasa cukup tertekan? sangat bagus. Mari mulakan dan selesaikan web. ✊
Konteks adalah penting
anda mungkin menyedari bahawa hambatan utama adalah masa yang diperlukan untuk memuatkan laman web. Khususnya, ia adalah muat turun JavaScript, parsing, penyusun dan masa pelaksanaan. Tidak ada lagi yang perlu dilakukan kecuali memuatkan kod JavaScript yang kurang dan memuat lebih bijak.
Tetapi bagaimana dengan kerja yang sebenarnya dilakukan oleh kod anda selain melancarkan laman web? Harus ada peningkatan prestasi di sana, bukan?
Sebelum menggali kod, pertimbangkan apa yang anda sedang bina. Adakah anda membina kerangka atau perpustakaan VDOM? Adakah kod anda memerlukan beribu -ribu operasi sesaat? Adakah anda menulis perpustakaan kritikal masa untuk memproses input pengguna dan/atau animasi? Jika tidak, anda mungkin perlu mengalihkan masa dan tenaga anda ke tempat yang lebih berkesan.
Ini bukan untuk mengatakan bahawa menulis kod berprestasi tinggi tidak penting, tetapi ia biasanya tidak memberi kesan kepada keadaan keseluruhan, terutama ketika bercakap tentang pengoptimuman mikro. Oleh itu, sebelum anda mula berdebat tentang .map versus .foreach versus untuk gelung pada limpahan stack dan membandingkan hasil di jsperf.com, pastikan anda melihat hutan, bukan hanya pokok -pokok. Di atas kertas, 50k ops/s mungkin terdengar 50 kali lebih baik daripada 1k ops/s, tetapi dalam kebanyakan kes ia tidak membuat sebarang perbezaan.
analisis, penyusunan dan pelaksanaan
Pada asasnya, masalah dengan kebanyakan prestasi JS bukan tinggi bukanlah kod yang berjalan itu sendiri, tetapi semua langkah yang diperlukan untuk dilakukan sebelum kod itu mula dilaksanakan. kita bercakap mengenai tahap abstraksi di sini. CPU dalam komputer anda menjalankan kod mesin. Kebanyakan kod yang berjalan di komputer anda dalam format binari yang disusun. (Berfikir tentang semua aplikasi elektron hari ini, saya bercakap tentang kod program
tanpa sebarang persediaan.JavaScript tidak dikompilasi. Ia tiba di penyemak imbas anda dalam bentuk kod yang boleh dibaca, dan untuk semua niat dan tujuannya adalah "sistem operasi" program JS anda. Kod pertama perlu dihuraikan - iaitu, dibaca dan ditukar menjadi struktur yang boleh diindeks oleh komputer untuk penyusunan. Kemudian menyusunnya ke bytecode dan akhirnya ke dalam kod mesin sebelum ia dapat dilaksanakan oleh peranti/penyemak imbas anda.
Satu lagi perkara yang sangat penting untuk disebutkan ialah JavaScript adalah satu berulir dan berjalan pada benang utama penyemak imbas. Ini bermakna hanya satu proses yang boleh dijalankan pada satu masa. Sekiranya garis masa prestasi DevTools anda penuh dengan puncak kuning yang memastikan CPU anda berjalan hingga 100%, anda akan berjalan ke dalam bingkai panjang/menjatuhkan, bergulir bergulir, dan segala macam perkara yang menjengkelkan.
Paul Lewis: Apabila semuanya penting, tidak ada perkara yang penting! .
Jadi, sebelum JS anda mula berfungsi, anda perlu melakukan semua ini. Dalam enjin V8 Chrome, parsing dan menyusun akaun sehingga 50% daripada jumlah masa pelaksanaan JS.
addy osmani: prestasi permulaan javascript.
Dua perkara yang harus anda ingat dari bahagian ini:
Walaupun tidak semestinya linear, masa parsing JS adalah berkadar dengan saiz paket. Lebih kecil jumlah kod JS, lebih baik.
Apa yang boleh anda lakukan, bagaimanapun, adalah untuk mengelakkan menggunakan kerangka animasi JS untuk segala -galanya dan memahami apa yang mencetuskan lukisan dan susun atur. Perpustakaan ini hanya digunakan jika peralihan dan animasi CSS biasa adalah mustahil untuk melaksanakan animasi.
Walaupun mereka boleh menggunakan peralihan CSS, sifat sintetik, dan requestAnimationFrame (), mereka masih berjalan di JS, pada benang utama. Mereka pada dasarnya hanya memukul Dom anda dengan gaya sebaris setiap 16 milisaat kerana hampir tidak ada yang perlu dilakukan. Untuk memastikan animasi lancar, anda perlu memastikan bahawa semua Js dapat dilaksanakan dalam 8 milisaat setiap bingkai.
Animasi dan peralihan CSS, sebaliknya, berjalan di luar benang utama -jika dilaksanakan dengan cekap, berjalan di GPU tanpa menyebabkan relayout/mengecat semula.
Memandangkan kebanyakan animasi dijalankan semasa pemuatan atau interaksi pengguna, ini dapat menyediakan ruang pernafasan yang sangat diperlukan untuk aplikasi web anda.
API Animasi Web adalah set ciri yang akan datang yang membolehkan anda melakukan animasi JS berprestasi tinggi di luar benang utama, tetapi buat masa ini, melekat dengan teknologi seperti peralihan CSS dan flip.
saiz belakang adalah penting
Sekarang, ini semua tentang pembungkusan. Bower dan pada akhir
berpuluh -puluh tanda sebelum menandakan era tanda telah berlalu.
Sekarang ini mengenai memasang mainan baru yang berkilat yang anda dapati di NPM, menggabungkannya ke dalam fail 1MB JS yang besar menggunakan webpack dan menyebabkan kelambatan dalam penyemak imbas pengguna anda sambil mengehadkan pelan data mereka.
Cuba mengurangkan jumlah kod JS. Projek anda mungkin tidak memerlukan seluruh perpustakaan Lodash. Adakah anda benar -benar perlu menggunakan kerangka JS? Jika ya, adakah anda mempertimbangkan menggunakan rangka kerja lain selain daripada bertindak balas, seperti preact atau hyperhtml, yang kurang daripada 1/20 reaksi? Adakah anda memerlukan tweenmax untuk melaksanakan menatal ke animasi teratas? Kemudahan mengasingkan komponen dalam NPM dan Rangka Kerja membawa kelemahan: Cara pertama bagi pemaju untuk menyelesaikan masalah menjadi menambah lebih banyak kod JavaScript. Semuanya kelihatan seperti kuku apabila anda hanya mempunyai tukul. Selepas menamatkan rumpai pemangkasan dan mengurangkan jumlah kod JS, cuba untuk menyampaikannya lebih banyak
dengan bijak. Sampaikan apa yang anda perlukan apabila diperlukan.Webpack 3 mempunyai ciri -ciri yang menakjubkan
yang dipanggil segmentasi kod dan import dinamik. Daripada menggabungkan semua modul JS ke dalam satu pakej APP.js tunggal, ia secara automatik boleh memecah kod menggunakan sintaks import () dan memuatkannya secara asynchronously.Anda juga tidak perlu menggunakan rangka kerja, komponen, dan penghalaan pelanggan untuk mendapatkan manfaatnya. Katakan anda mempunyai sekeping kod kompleks yang menyokong .mega-Widget anda, yang boleh ditempatkan di mana-mana halaman. Anda hanya perlu menulis perkara berikut dalam fail JS utama:
Jika aplikasi anda mendapati widget pada halaman, ia secara dinamik akan memuatkan kod tambahan yang diperlukan. Jika tidak, semuanya adalah perkara biasa.
<code class="language-javascript">if (document.querySelector('.mega-widget')) { import('./mega-widget'); }</code>Di samping itu, Webpack memerlukan runtime sendiri untuk berfungsi, dan ia menyuntiknya ke dalam semua fail .js yang dihasilkannya. Jika anda menggunakan plugin CommonChunks, anda boleh mengekstrak runtime ke dalam blok sendiri menggunakan kaedah berikut:
Ia melepaskan runtime dari semua blok lain ke dalam failnya sendiri, dalam kes ini dipanggil runtime.js. Hanya pastikan ia dimuatkan sebelum pakej JS utama. Contohnya:
<code class="language-javascript">new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', }),</code>maka terdapat topik menterjemahkan kod dan polyfill. Jika anda menulis JavaScript Modern (ES6), anda mungkin menggunakan Babel untuk menterjemahkannya ke dalam kod yang serasi ES5. Terjemahan bukan sahaja meningkatkan saiz fail kerana semua redundansi, ia juga meningkatkan kerumitan, dan ia sering mengurangkan prestasi berbanding dengan kod ES6 asli.
Selain itu, anda juga boleh menggunakan pakej Babel-Polyfill dan apa yang dipasang untuk menampal ciri-ciri yang hilang dalam pelayar yang lebih tua. Kemudian, jika anda menulis kod menggunakan async/menunggu, anda juga perlu menggunakan penjana untuk menterjemahkannya untuk memasukkan regenerator-runtime ...
<code class="language-html"> </code>
Kuncinya ialah anda menambah hampir 100 kilobytes data ke pakej JS, yang bukan hanya besar dalam saiz fail, tetapi juga besar dalam parsing dan kos pelaksanaan, yang bertujuan untuk menyokong pelayar yang lebih tua.
cara yang tidak cekap tetapi berkesan adalah meletakkan perkara berikut dalam skrip sebaris:
<code class="language-javascript">if (document.querySelector('.mega-widget')) { import('./mega-widget'); }</code>Jika penyemak imbas tidak dapat menilai fungsi asynchronous, kami menganggap ia adalah pelayar lama dan hanya menyampaikan pakej yang mengandungi polyfill. Jika tidak, pengguna akan mendapat versi yang mudah dan moden.
Kesimpulan
kami berharap anda akan mendapat dari artikel ini bahawa JavaScript menggunakan banyak prestasi dan harus digunakan dengan berhati -hati.Pastikan anda menguji prestasi laman web dalam peranti rendah dan persekitaran rangkaian sebenar. Laman web anda harus dimuat dengan cepat dan berinteraksi secepat mungkin. Ini bermakna mengurangkan jumlah kod JS dan mempercepatkan pemuatan secepat mungkin. Kod anda harus sentiasa dimampatkan, berpecah menjadi lebih kecil, lebih mudah untuk menguruskan pakej, dan memuatkan secara tidak segerak di mana mungkin. Di sisi pelayan, pastikan HTTP/2 diaktifkan untuk pemindahan selari yang lebih cepat dan gunakan mampatan GZIP/Brotli untuk mengurangkan saiz pemindahan JS dengan ketara.
bercakap tentang ini, saya ingin menamatkannya dengan tweet berikut:
Saya perlu meletakkan banyak usaha untuk mencapai matlamat ini. Tetapi dengan serius, kawan -kawan, sudah tiba masanya untuk meninggalkan rangka kerja anda dan melihat seberapa cepat penyemak imbas boleh.- Alex Russell (@Slightlylate) 15 September 2016
Apakah perangkap prestasi JavaScript biasa yang harus dielakkan?
gelung adalah ciri umum dalam JavaScript, tetapi mereka juga boleh menjadi sumber isu prestasi jika tidak dioptimumkan dengan betul. Salah satu cara untuk mengoptimumkan gelung adalah untuk meminimumkan kerja yang dilakukan dalam gelung. Sebagai contoh, bukannya mengira panjang array dalam setiap lelaran, hitung sekali sebelum gelung bermula. Cara lain ialah menggunakan gelung yang paling berkesan mengikut keperluan anda. Sebagai contoh, kaedah foreach () mungkin lebih perlahan daripada tradisional untuk gelung.
ketinggian adalah mekanisme dalam JavaScript di mana pembolehubah dan pengisytiharan fungsi dipindahkan ke bahagian atas skop mereka yang disertakan semasa fasa kompilasi. Jika tidak difahami dengan betul, ini boleh membawa kepada tingkah laku yang tidak dijangka dan isu -isu prestasi yang berpotensi. Sebagai contoh, jika sejumlah besar data dibangkitkan tetapi tidak digunakan dengan serta -merta, promosi boleh mengakibatkan penggunaan memori yang tidak perlu. Memahami ketinggian dan menggunakan LeT dan Const dan bukannya VAR dapat membantu mengurangkan masalah ini.
Apabila memori tidak lagi diperlukan tidak dikeluarkan, kebocoran memori berlaku, menyebabkan prestasi menurun dari masa ke masa. Punca kebocoran memori yang biasa di JavaScript termasuk pemasa atau panggilan balik yang dilupakan, elemen DOM yang berasingan, dan pembolehubah global. Untuk mengelakkan kebocoran memori, pastikan untuk membersihkan selang waktu dan tamat, padamkan pendengar acara apabila mereka tidak lagi diperlukan, dan elakkan pembolehubah global apabila mungkin.
JavaScript menyediakan pelbagai alat terbina dalam untuk analisis prestasi dan pengoptimuman. API Prestasi membolehkan anda mengukur masa yang dihabiskan di bahagian yang berlainan kod anda dan membantu anda mengenal pasti kesesakan. API memori membantu anda mengesan penggunaan memori dan mengenal pasti kebocoran yang berpotensi. Di samping itu, alat pemaju penyemak imbas sering menyediakan keupayaan analisis prestasi yang dapat membantu anda mengoptimumkan kod anda.
Pengaturcaraan Asynchronous membolehkan JavaScript melakukan operasi yang tidak menyekat, meningkatkan prestasi dengan membenarkan kod lain berjalan sambil menunggu operasi tak segerak diselesaikan. Walau bagaimanapun, penggunaan pengaturcaraan tak segerak yang tidak betul boleh menyebabkan masalah prestasi. Sebagai contoh, menggunakan terlalu banyak janji atau panggilan balik boleh membawa kepada "panggil balik neraka" dan kemerosotan prestasi. Belajar cara menggunakan async/menunggu, janji, dan panggilan balik dengan betul dapat membantu mengoptimumkan kod asynchronous anda.
Mengoptimumkan JavaScript untuk peranti mudah alih memerlukan pertimbangan faktor seperti keupayaan CPU terhad dan latensi rangkaian. Teknik untuk pengoptimuman mudah alih termasuk meminimumkan jumlah kod JavaScript yang dihantar melalui rangkaian, menggunakan amalan pengekodan yang cekap untuk mengurangkan penggunaan CPU, dan menggunakan peningkatan progresif untuk memastikan laman web anda berfungsi dengan baik walaupun pada peranti kuasa rendah.
pemampatan dan mampatan mengurangkan saiz fail JavaScript, yang mempercepat muat turun dan meningkatkan prestasi. Mampatan melibatkan memadam watak -watak yang tidak perlu seperti ruang dan komen, sementara mampatan melibatkan data pengekodan dalam format yang lebih efisien. Kedua -dua teknologi dapat meningkatkan kelajuan pemuatan laman web dengan ketara, terutama bagi pengguna dengan rangkaian yang lebih perlahan.
Pekerja web membolehkan anda menjalankan JavaScript pada benang berasingan di latar belakang tanpa menyekat benang utama. Ini berguna untuk melaksanakan tugas-tugas intensif tanpa melambatkan antara muka pengguna. Walau bagaimanapun, pekerja web mempunyai beberapa batasan dan kos, seperti overhead memulakan benang pekerja baru dan keupayaan untuk mengendalikan DOM secara langsung, jadi ia harus digunakan dengan berhati -hati.
Atas ialah kandungan terperinci Petua Pengoptimuman Prestasi JavaScript: Gambaran Keseluruhan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!