Saat membangun situs yang sangat bergantung pada JavaScript, terkadang kita harus membayar apa yang kita kirimkan dengan cara yang tidak selalu mudah dilihat. Dalam artikel ini, kami akan membahas alasan sedikit disiplin dapat membantu jika Anda ingin situs Anda 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. Mengirim lebih banyak byte JavaScript melalui jaringan akan memerlukan waktu lebih lama jika koneksi pengguna lebih lambat.

Hal ini dapat menjadi masalah, karena jenis koneksi jaringan 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 dibutuhkan pengguna.
- Gunakan pemisahan kode untuk memisahkan JavaScript menjadi bagian yang penting dan tidak penting. Bundler modul seperti webpack mendukung pemisahan kode.
- Pemuatan lambat dalam kode yang tidak penting.
- Minifikasi
- Gunakan UglifyJS untuk meminifikasi kode ES5.
- Gunakan babel-minify atau uglify-es untuk meminimalkan ES2015+.
- Kompresi
- Menghapus kode yang tidak digunakan.
- Identifikasi peluang untuk kode yang dapat dihapus atau dimuat lambat dengan cakupan kode DevTools.
- Gunakan babel-preset-env dan browserlist untuk menghindari transpiling fitur yang sudah ada di browser modern. Developer tingkat lanjut mungkin akan menemukan bahwa analisis yang cermat terhadap paket webpack membantu mengidentifikasi peluang untuk memangkas dependensi yang tidak diperlukan.
- Untuk menghapus kode, lihat tree-shaking, pengoptimalan lanjutan Closure Compiler, dan plugin pemangkasan library seperti lodash-babel-plugin atau ContextReplacementPlugin webpack untuk library seperti Moment.js.
- Men-cache kode untuk meminimalkan perjalanan jaringan.
- Gunakan caching HTTP untuk memastikan browser meng-cache respons secara efektif. Tentukan masa aktif optimal untuk skrip (max-age) dan berikan token validasi (ETag) untuk menghindari transfer byte yang tidak berubah.
- Caching Service Worker dapat membuat jaringan aplikasi Anda tangguh dan memberi Anda akses cepat ke fitur seperti cache kode V8.
- Gunakan caching jangka panjang untuk menghindari pengambilan 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 mengurai/mengompilasi kode ini. Di Chrome DevTools, penguraian dan kompilasi adalah bagian dari waktu "Pembuatan skrip" berwarna kuning di panel Performa.

Tab Bottom-Up dan Call Tree menampilkan waktu Parse/compile yang tepat:
Namun, mengapa hal ini penting?

Menghabiskan waktu lama untuk mengurai/mengompilasi kode dapat sangat menunda seberapa cepat pengguna dapat berinteraksi dengan situs Anda. Semakin banyak JavaScript yang Anda kirim, semakin lama waktu yang diperlukan untuk mengurai dan mengompilasinya sebelum situs Anda menjadi interaktif.
Byte demi byte, JavaScript lebih mahal untuk diproses oleh browser daripada gambar atau Font Web dengan ukuran yang setara — Tom Dale
Dibandingkan dengan JavaScript, ada banyak biaya yang terkait dengan pemrosesan gambar berukuran setara (gambar tersebut masih harus didekode), tetapi pada hardware seluler rata-rata, JS lebih cenderung berdampak negatif pada interaktivitas halaman.
Saat kita membahas tentang lambatnya penguraian dan kompilasi, konteksnya penting — kita membahas tentang ponsel rata-rata di sini. Pengguna rata-rata dapat memiliki ponsel dengan CPU dan GPU yang lambat, tanpa cache L2/L3, dan bahkan mungkin memiliki batasan memori.
Kemampuan jaringan dan kemampuan perangkat tidak selalu cocok. Pengguna dengan koneksi Fiber yang luar biasa belum tentu memiliki CPU terbaik untuk mengurai dan mengevaluasi JavaScript yang dikirim ke perangkatnya. 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 (sederhana) yang didekompresi sebesar ~1 MB pada hardware kelas bawah dan atas. Ada perbedaan waktu 2–5x untuk mengurai/mengompilasi kode antara ponsel tercepat di pasar 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 berdampak signifikan pada seberapa cepat pengguna dapat berinteraksi sepenuhnya dengan situs ini.
Hal ini menekankan pentingnya pengujian pada hardware rata-rata (seperti Moto G4), bukan hanya ponsel yang mungkin ada di saku Anda. Namun, konteks itu penting: optimalkan untuk perangkat dan kondisi jaringan yang dimiliki pengguna Anda.
Apakah kita benar-benar mengirimkan terlalu banyak JavaScript? Err, possibly :)
Dengan menggunakan HTTP Archive (sekitar 500 ribu situs teratas) 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.

Dengan mempertimbangkan waktu yang diperlukan untuk mengambil dan memproses JS serta resource lainnya, 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 yang tidak penting dari halaman Anda dapat mengurangi waktu transmisi, penguraian dan kompilasi yang menggunakan banyak CPU, serta potensi overhead memori. Hal ini juga membantu membuat halaman Anda interaktif lebih cepat.
Waktu eksekusi
Tidak hanya penguraian dan kompilasi yang dapat menimbulkan biaya. Eksekusi JavaScript (menjalankan kode setelah diurai/dikompilasi) adalah salah satu operasi yang harus terjadi di thread utama. Waktu eksekusi yang lama juga dapat memperlambat seberapa cepat pengguna dapat berinteraksi dengan situs Anda.

Jika skrip dieksekusi selama lebih dari 50 milidetik, waktu interaktif akan tertunda selama seluruh waktu yang diperlukan untuk mendownload, mengompilasi, dan mengeksekusi JS — Alex Russell
Untuk mengatasinya, JavaScript mendapatkan manfaat dari bagian kecil untuk menghindari penguncian thread utama. Pelajari apakah Anda dapat mengurangi jumlah pekerjaan yang dilakukan selama eksekusi.
Biaya lain
JavaScript dapat memengaruhi performa halaman dengan cara lain:
- Memori. Halaman dapat tampak tersendat atau sering dijeda 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 untuk menjaga halaman bebas jank.
- Selama runtime, JavaScript yang berjalan lama dapat memblokir thread utama sehingga menyebabkan halaman tidak responsif. Membagi 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 menjaga waktu transmisi jaringan dan penguraian/kompilasi untuk JavaScript tetap lambat, 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 kode dan caching yang agresif:

Mari kita visualisasikan dampaknya.
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 penting dari waktu yang dihabiskan banyak situs ini:

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 menerapkan pemisahan kode dan anggaran performa untuk mencoba menurunkan biaya JS mereka.
Bootstrapping 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 "mengupgradenya" untuk melampirkan pengendali peristiwa saat JavaScript akhirnya diambil.
Berhati-hatilah — hal ini memiliki biaya tersendiri. Anda 1) umumnya mengirimkan respons HTML yang lebih besar yang dapat mendorong interaktivitas kita, 2) dapat membuat pengguna berada dalam lembah yang luar biasa di mana separuh pengalaman tidak dapat benar-benar interaktif hingga JavaScript selesai diproses.
Bootstrap Progresif mungkin merupakan pendekatan yang lebih baik. Kirim halaman dengan fungsi minimal (hanya terdiri dari HTML/JS/CSS yang diperlukan untuk rute saat ini). Seiring dengan tersedianya lebih banyak resource, aplikasi dapat melakukan pemuatan lambat dan membuka lebih banyak fitur.
Memuat kode yang proporsional dengan apa yang terlihat adalah hal yang ideal. PRPL dan Progressive Bootstrapping adalah pola yang dapat membantu mencapai hal ini.
Kesimpulan
Ukuran transmisi sangat penting untuk jaringan low-end. Waktu penguraian penting untuk perangkat yang terikat CPU. Menjaga latensi ini tetap rendah sangatlah penting.
Tim telah berhasil menerapkan anggaran performa yang ketat untuk menjaga waktu transmisi dan penguraian/waktu kompilasi JavaScript tetap rendah. Lihat "Can You Afford It?: Real-world Web Performance Budgets" untuk mendapatkan panduan tentang anggaran untuk perangkat seluler.
Jika Anda membangun situs yang menargetkan perangkat seluler, lakukan yang terbaik untuk mengembangkan pada hardware yang representatif, jaga agar waktu penguraian/waktu kompilasi JavaScript tetap rendah dan terapkan anggaran performa untuk memastikan tim Anda dapat mengawasi biaya JavaScript mereka.
Pelajari lebih lanjut
- Chrome Dev Summit 2017 - Praktik Terbaik Pemuatan Modern
- Performa Startup JavaScript
- Mengatasi krisis performa web — Nolan Lawson
- Apakah Anda mampu 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 render halaman awal, jadi evaluasi dengan cermat. Sebaiknya kompresi secara statis.)
- Performance Futures — Sam Saccone