Saat membuat situs yang lebih mengandalkan JavaScript, terkadang kami membayar apa yang kami kirim dengan cara yang tidak selalu mudah dilihat. Dalam artikel ini, kami akan menjelaskan mengapa sedikit disiplin dapat membantu jika Anda ingin situs dimuat dan interaktif dengan cepat di perangkat seluler. Mengirimkan lebih sedikit JavaScript dapat berarti lebih sedikit waktu dalam transmisi jaringan, lebih sedikit waktu yang dihabiskan untuk mendekompresi kode, dan lebih sedikit waktu untuk mengurai dan mengompilasi JavaScript ini.
Jaringan
Saat sebagian besar developer memikirkan biaya JavaScript, mereka memikirkannya dalam hal biaya download dan eksekusi. Semakin lambat koneksi pengguna, semakin lama waktu yang diperlukan untuk mengirim lebih banyak byte JavaScript melalui jaringan.
Hal ini dapat menjadi masalah, karena jenis koneksi jaringan yang efektif yang dimiliki pengguna mungkin sebenarnya bukan 3G, 4G, atau Wi-Fi. Anda dapat menggunakan Wi-Fi kedai kopi, tetapi terhubung ke hotspot seluler dengan kecepatan 2G.
Anda dapat mengurangi biaya transfer jaringan JavaScript melalui:
- Hanya mengirim kode yang diperlukan pengguna.
- Gunakan pemisahan kode untuk membagi JavaScript menjadi bagian yang penting dan tidak penting. Penggabung modul seperti webpack mendukung pemisahan kode.
- Memuat kode yang tidak penting secara lambat.
- Minifikasi
- Gunakan UglifyJS untuk miminifikasi kode ES5.
- Gunakan babel-minify atau uglify-es untuk meminifikasi ES2015+.
- Kompresi
- Menghapus kode yang tidak digunakan.
- Identifikasi peluang untuk kode yang dapat dihapus atau dimuat secara lambat dengan cakupan kode DevTools.
- Gunakan babel-preset-env dan browserlist untuk menghindari transpilasi fitur yang sudah ada di browser modern. Developer tingkat lanjut mungkin menemukan bahwa analisis paket webpack mereka yang cermat membantu mengidentifikasi peluang untuk memangkas dependensi yang tidak diperlukan.
- Untuk menghapus kode, lihat tree-shaking, pengoptimalan lanjutan Closure Compiler, dan plugin pemotongan library seperti lodash-babel-plugin atau ContextReplacementPlugin webpack untuk library seperti Moment.js.
- Menyimpan kode dalam cache untuk meminimalkan perjalanan jaringan.
- Gunakan cache HTTP untuk memastikan browser menyimpan respons dalam cache secara efektif. Tentukan masa aktif yang optimal untuk skrip (max-age) dan token validasi pasokan (ETag) untuk menghindari transfer byte yang tidak berubah.
- Cache Pekerja Layanan dapat membuat jaringan aplikasi Anda tangguh dan memberi Anda akses cepat ke fitur seperti cache kode V8.
- Gunakan cache jangka panjang agar tidak perlu mengambil ulang resource yang belum berubah. Jika menggunakan Webpack, lihat hashing nama file.
Mengurai/Mengompilasi
Setelah didownload, salah satu biaya terberat JavaScript adalah waktu yang diperlukan mesin JS untuk menguraikan/mengompilasi kode ini. Di Chrome DevTools, penguraian dan kompilasi adalah bagian dari waktu "Pembuatan skrip" kuning di panel Performa.
Tab Bottom-Up dan Call Tree menampilkan waktu Parse/kompilasi yang tepat:

Namun, mengapa hal ini penting?
Memerlukan waktu lama untuk mengurai/mengompilasi kode dapat sangat menunda waktu pengguna dapat berinteraksi dengan situs Anda. Makin banyak JavaScript yang Anda kirim, makin lama waktu yang diperlukan untuk mengurai dan mengompilasi JavaScript sebelum situs Anda menjadi interaktif.
Byte demi byte, JavaScript lebih mahal untuk diproses browser daripada gambar atau Font Web dengan ukuran yang setara — Tom Dale
Dibandingkan dengan JavaScript, ada banyak biaya yang terlibat dalam pemrosesan gambar berukuran setara (gambar masih harus didekode), tetapi pada hardware seluler rata-rata, JS cenderung berdampak negatif pada interaktivitas halaman.

Saat kita membahas penguraian dan kompilasi yang lambat, konteks itu penting — kita membahas ponsel rata-rata di sini. Pengguna rata-rata dapat memiliki ponsel dengan CPU dan GPU lambat, tanpa cache L2/L3, dan bahkan mungkin memiliki memori yang terbatas.
Kemampuan jaringan dan kemampuan perangkat tidak selalu cocok. Pengguna dengan koneksi Fiber yang luar biasa belum tentu memiliki CPU terbaik untuk menguraikan dan mengevaluasi JavaScript yang dikirim ke perangkat mereka. Hal ini juga berlaku sebaliknya… koneksi jaringan yang buruk, tetapi CPU yang sangat cepat. — Kristofer Baxter, LinkedIn
Di bawah ini, kita dapat melihat biaya penguraian JavaScript yang didekompresi (sederhana) sebesar ~1 MB pada hardware kelas bawah dan kelas atas. Ada perbedaan waktu 2–5x untuk mengurai/mengompilasi kode antara ponsel tercepat di pasaran dan ponsel rata-rata.

Bagaimana dengan situs di dunia nyata, seperti CNN.com?
Di iPhone 8 kelas atas, hanya perlu waktu ~4 detik untuk mengurai/mengompilasi JS CNN dibandingkan dengan ~13 detik untuk ponsel biasa (Moto G4). Hal ini dapat secara signifikan memengaruhi kecepatan pengguna berinteraksi sepenuhnya dengan situs ini.

Hal ini menyoroti pentingnya pengujian pada hardware rata-rata (seperti Moto G4), bukan hanya ponsel yang mungkin ada di saku Anda. Namun, konteks itu penting: optimalkan untuk kondisi perangkat dan jaringan yang dimiliki pengguna Anda.

Apakah kita benar-benar mengirim terlalu banyak JavaScript? Mungkin saja :)
Dengan menggunakan HTTP Archive (situs teratas ~500 ribu) untuk menganalisis status JavaScript di perangkat seluler, kita dapat melihat bahwa 50% situs memerlukan waktu lebih dari 14 detik untuk menjadi interaktif. Situs ini menghabiskan hingga 4 detik hanya untuk mengurai dan mengompilasi JS.
Pertimbangkan waktu yang diperlukan untuk mengambil dan memproses JS dan resource lainnya. Jadi, mungkin tidak mengherankan jika pengguna harus menunggu beberapa saat sebelum merasa halaman siap digunakan. Kita pasti bisa melakukan yang lebih baik di sini.
Menghapus JavaScript non-kritis dari halaman dapat mengurangi waktu transmisi, penguraian dan kompilasi yang intensif CPU, serta potensi overhead memori. Hal ini juga membantu membuat halaman Anda lebih interaktif dengan lebih cepat.
Waktu eksekusi
Tidak hanya penguraian dan kompilasi yang dapat menimbulkan biaya. Eksekusi JavaScript (menjalankan kode setelah diuraikan/dikompilasi) adalah salah satu operasi yang harus terjadi di thread utama. Waktu eksekusi yang lama juga dapat memperlambat waktu yang diperlukan pengguna untuk berinteraksi dengan situs Anda.
Jika skrip dieksekusi selama lebih dari 50 md, waktu untuk interaktif akan tertunda oleh seluruh waktu yang diperlukan untuk mendownload, mengompilasi, dan mengeksekusi JS — Alex Russell
Untuk mengatasi hal ini, JavaScript akan diuntungkan jika berada dalam potongan kecil untuk menghindari kunci thread utama. Pelajari apakah Anda dapat mengurangi jumlah pekerjaan yang dilakukan selama eksekusi.
Biaya lainnya
JavaScript dapat memengaruhi performa halaman dengan cara lain:
- Memori. Halaman dapat sering mengalami jank atau jeda karena GC (pembersihan sampah memori). Saat browser mengklaim kembali memori, eksekusi JS dijeda sehingga browser yang sering mengumpulkan sampah dapat menjeda eksekusi lebih sering daripada yang kita inginkan. Hindari kebocoran memori dan jeda gc yang sering terjadi agar halaman bebas jank.
- Selama runtime, JavaScript yang berjalan lama dapat memblokir thread utama sehingga
halaman tidak responsif. Memecah pekerjaan menjadi bagian-bagian yang lebih kecil (menggunakan
requestAnimationFrame()
ataurequestIdleCallback()
untuk penjadwalan) dapat meminimalkan masalah responsivitas yang dapat membantu meningkatkan Interaction to Next Paint (INP).
Pola untuk mengurangi biaya pengiriman JavaScript
Saat Anda mencoba memperlambat waktu penguraian/kompilasi dan transmisi jaringan untuk JavaScript, ada pola yang dapat membantu seperti pengelompokan berbasis rute atau PRPL.
PRPL
PRPL (Push, Render, Pre-cache, Lazy-load) adalah pola yang mengoptimalkan interaktivitas melalui pemisahan dan penyimpanan dalam cache kode yang agresif:
Mari kita visualisasi dampak yang dapat ditimbulkan.
Kami menganalisis waktu pemuatan situs seluler populer dan Progressive Web App menggunakan Statistik Panggilan Runtime V8. Seperti yang dapat kita lihat, waktu penguraian (ditampilkan dalam warna oranye) adalah bagian yang signifikan dari tempat banyak situs ini menghabiskan waktu:
Wego, situs yang menggunakan PRPL, berhasil mempertahankan waktu penguraian yang rendah untuk rutenya, sehingga menjadi interaktif dengan sangat cepat. Banyak situs lain di atas yang mengadopsi pemisahan kode dan anggaran performa untuk mencoba menurunkan biaya JS mereka.
Bootstrap Progresif
Banyak situs mengoptimalkan visibilitas konten dengan mengorbankan interaktivitas. Untuk mendapatkan first paint yang cepat saat Anda memiliki paket JavaScript yang besar, developer terkadang menggunakan rendering sisi server; lalu "mengupgrade"nya untuk melampirkan pengendali peristiwa saat JavaScript akhirnya diambil.
Berhati-hatilah — hal ini memiliki biayanya sendiri. Anda 1) umumnya mengirimkan respons HTML yang lebih besar yang dapat mendorong interaktivitas, 2) dapat membuat pengguna berada dalam lembah aneh, yaitu setengah pengalaman tidak dapat benar-benar interaktif hingga JavaScript selesai diproses.
Bootstrapping Progresif mungkin merupakan pendekatan yang lebih baik. Kirim halaman yang berfungsi minimal (hanya terdiri dari HTML/JS/CSS yang diperlukan untuk rute saat ini). Seiring dengan semakin banyaknya resource yang tiba, aplikasi dapat melakukan pemuatan lambat dan membuka lebih banyak fitur.

Memuat kode yang sebanding dengan apa yang terlihat adalah hal yang sangat penting. PRPL dan Progressive Bootstrapping adalah pola yang dapat membantu mencapai hal ini.
Kesimpulan
Ukuran transmisi sangat penting untuk jaringan kelas bawah. Waktu penguraian penting untuk perangkat yang terikat CPU. Penting untuk menjaga agar hal-hal ini tetap rendah.
Tim telah berhasil menerapkan anggaran performa yang ketat untuk menjaga waktu transmisi dan penguraian/kompilasi JavaScript tetap rendah. Lihat "Can You Afford It?: Real-world Web Performance Budgets" untuk mendapatkan panduan tentang anggaran untuk perangkat seluler.

Jika Anda membuat situs yang menargetkan perangkat seluler, lakukan yang terbaik untuk mengembangkannya di hardware yang representatif, pertahankan waktu penguraian/kompilasi JavaScript Anda tetap rendah, dan terapkan Anggaran Performa untuk memastikan tim Anda dapat memantau biaya JavaScript mereka.
Pelajari Lebih Lanjut
- Chrome Dev Summit 2017 - Praktik Terbaik Memuat Modern
- Performa Awal JavaScript
- Memecahkan krisis performa web — Nolan Lawson
- Mampukah Anda membelinya? Anggaran performa di dunia nyata — Alex Russell
- Mengevaluasi framework dan library web — Kristofer Baxter
- Hasil eksperimen Cloudflare dengan Brotli untuk kompresi (perhatikan bahwa Brotli dinamis dengan kualitas yang lebih tinggi dapat menunda rendering halaman awal, jadi evaluasi dengan cermat. Sebaiknya Anda mengompresi secara statis.)
- Performance Future — Sam Saccone