Minifier JavaScript
Kompresi kode JavaScript dengan menghapus komentar, spasi, dan karakter yang tidak perlu.
Tentang minifikasi JavaScript
JavaScript adalah jenis sumber daya paling berat di sebagian besar halaman web, dan tidak hanya karena cenderung menjadi file terbesar. Biayanya dalam lima tahap: unduh (melalui jaringan), parse (engine membaca byte dan membangun AST), compile (V8 atau JavaScriptCore mengompilasi AST ke bytecode), jalankan (bytecode berjalan), dan pada kunjungan berikutnya, warm-start dari bytecode yang di-cache jika engine menyimpannya. Brotli di edge CDN menangani biaya unduh. Minifikasi juga membantu dengan unduh, tetapi juga membantu dengan biaya parse dan compile di setiap perangkat yang mengunduh skrip Anda, dan di ponsel Android kelas bawah, parse dan compile dapat memakan waktu lebih lama daripada transfer jaringan. Artikel Cost of JavaScript Addy Osmani telah berulang kali menunjukkan bahwa apa yang terlihat seperti masalah jaringan sering kali merupakan masalah CPU, dan bahwa pengurangan byte 20-40% dari minifikasi diterjemahkan cukup langsung menjadi milidetik yang dipangkas dari waktu parse di ekor panjang perangkat lambat.
Optimasi lazy parsing V8 menunda parsing penuh fungsi apa pun sampai benar-benar dipanggil, yang berarti skrip besar dengan banyak fungsi yang tidak digunakan biayanya lebih rendah daripada jumlah bytenya. Cache HTTP Chrome juga menyimpan bytecode V8 ("Code Cache") sehingga kunjungan berulang melewati tahap parse-and-compile sepenuhnya. Tidak ada ini yang mengubah persamaan dasar: skrip yang lebih kecil mengenai cache hangat lebih cepat, parse lebih cepat di jalur dingin, dan compile lebih cepat. Minifikasi adalah tempat termurah di seluruh stack untuk mengambil kembali milidetik.
Empat (atau Lima) Tingkat Minifikasi JavaScript
Tidak semua minifier sama, dan tingkat yang Anda butuhkan tergantung pada basis kode Anda. Tingkat 1: penghapusan spasi dan komentar. Pass paling sederhana, hilangkan spasi, tab, newline dan komentar // ... / /* ... */. Ini adalah apa yang dapat dilakukan dengan aman oleh pass regex (dengan hati-hati di sekitar string, template literal dan literal regex). Pengurangan tipikal: 20-40% dalam byte mentah. Tingkat 2: penggantian nama simbol (mangling). Nama variabel lokal, parameter fungsi dan (dengan hati-hati) nama fungsi ditulis ulang ke huruf tunggal: function calculateTotal(itemList) menjadi function a(b). Ini memerlukan Abstract Syntax Tree dan analisis scope penuh untuk mengetahui nama mana yang aman untuk diganti namanya, nama global, ekspor, referensi ke properti this, dan apa pun yang dijangkau melalui akses kunci string (obj['name']) semuanya harus tetap utuh. Pengurangan tambahan tipikal: 10-25%. Tingkat 3: eliminasi kode mati (tree shaking). Analisis statis tingkat modul mengidentifikasi impor dan jalur kode yang tidak pernah dijalankan dan menghapusnya. Memerlukan informasi tipe tingkat modul dan pemahaman yang jelas tentang efek samping. Pengurangan tambahan tipikal: variabel, tetapi bisa sangat besar pada pustaka yang mengirimkan banyak fitur. Tingkat 4: inlining dan constant folding. Ekspresi sederhana seperti 2 * 60 * 60 dievaluasi pada waktu build menjadi 7200; fungsi kecil yang dipanggil sekali mungkin di-inline ke pemanggilnya. Tingkat 5: property mangling. Optimasi paling agresif, nama properti objek juga ditulis ulang. Memecahkan kode apa pun yang menggunakan kunci string (obj['name'] vs obj.name) atau yang mengekspos nama properti sebagai bagian dari kontrak publiknya. Hampir selalu opt-in dan hampir selalu terbatas pada pengidentifikasi spesifik melalui regex --mangle-props.
Sejarah Singkat Tooling Minifikasi JavaScript
JSMin (2003). Douglas Crockford, ya, Crockford yang sama yang mempromosikan JSON, menulis JSMin dalam C pada 2003. Itu adalah program file tunggal kecil yang melakukan penghapusan spasi dan komentar dasar tanpa AST, tanpa analisis scope, dan dengan pendekatan yang sengaja konservatif untuk kasus tepi ASI (Automatic Semicolon Insertion). Itu menetapkan batas untuk "hal paling sederhana yang berfungsi" dan merupakan nenek moyang spiritual dari setiap minifier JS berbasis regex sejak saat itu. YUI Compressor (2007). Julien Lecomte dari Yahoo mengumumkan YUI Compressor pada 11 Agustus 2007. Itu menggunakan tokenizer Rhino untuk melakukan penggantian nama simbol yang aman, alat Java pertama yang digunakan secara luas untuk melakukan mangling berbasis AST nyata untuk JavaScript. Closure Compiler (2009). Google telah menggunakannya secara internal sejak 2005; mereka meng-open-source-kannya di bawah Apache 2.0 pada 5 November 2009. Closure adalah pengoptimal paling agresif pada era itu, sadar-tipe melalui anotasi JSDoc, dengan mode "advanced" yang dapat menulis ulang nama properti berdasarkan inferensi tipe. Trade-off-nya adalah Anda harus menulis kode dengan cara yang ramah-Closure; kegagalan mode advanced terkenal.
UglifyJS (~2010-2012). UglifyJS Mihai Bazon adalah minifier JavaScript-native pertama, ditulis dalam JS, dijalankan di Node.js, dan menjadi default npm selama satu dekade. UglifyJS 2 menambahkan dukungan source map dan fitur ES5; UglifyJS 3 mengikuti dengan polish ES5 yang berkelanjutan tetapi tidak pernah sepenuhnya mendapatkan dukungan ES6+. Terser (Agustus 2018). Fabricio Matté mem-fork UglifyJS ke Terser khusus untuk menambahkan dukungan ES6+ tanpa mengganggu API UglifyJS yang stabil lama. Terser sekarang adalah minifier JS default di webpack 5, Rollup, Parcel 1, dan versi Next.js yang lebih lama. swc (2017/2019). swc Donny "kdy1" Choi ("Speedy Web Compiler") adalah compiler JavaScript/TypeScript berbasis Rust dengan minifier bawaan yang 20-70x lebih cepat dari Terser. Next.js mengubah minifier defaultnya dari Terser ke swc mulai dari versi 12 pada Oktober 2021. esbuild (musim dingin 2019-2020). Evan Wallace, co-founder Figma, merilis esbuild selama liburan musim dingin 2019-2020. Ditulis dalam Go, itu 10-100x lebih cepat dari bundler berbasis JavaScript pada hari itu dan mengirim minifier-nya sendiri. esbuild sekarang adalah minifier yang mendasari di Vite, di tsup, dan di banyak template framework. Arah umum selama lima tahun terakhir adalah: parser ditulis dalam bahasa sistem cepat (Rust atau Go), optimasi berbasis AST, tree shaking yang sadar modul ES yang cerdas. Minifier regex yang ditempel di browser, seperti alat ini, duduk di bagian bawah tangga itu, melakukan pekerjaan paling sederhana yang masih berguna.
Source Map untuk JavaScript yang Diminify
Source map adalah file sidecar JSON yang memetakan posisi dalam output yang diminify kembali ke posisi dalam sumber asli. Spesifikasi Source Map V3 ditulis oleh John Lenz (Google) dan Nick Fitzgerald (Mozilla) pada 2011, dan diadopsi oleh TC39 sebagai ECMA-426 pada Juni 2024, format source-map yang sama berlaku untuk JavaScript dan CSS. Browser mengonsumsi peta melalui komentar trailing di file yang diminify: //# sourceMappingURL=app.js.map. Ketika DevTools terbuka dan peta diambil, panel Sources menampilkan sumber asli, dengan breakpoint, kesalahan konsol dan jejak tumpukan semuanya merujuk kembali ke sana. Minifier produksi (Terser, swc, esbuild, Closure) semuanya mengeluarkan source map atas permintaan. Alat ini tidak, untuk alat one-shot di browser yang mengembalikan teks daripada pasangan file yang dapat diunduh, source map menambah kompleksitas yang signifikan untuk manfaat marginal. Pengungkapan jujur adalah bahwa alat ini adalah pass satu arah; minifier build-pipeline memiliki kasus yang jauh lebih kuat untuk source map karena sumber asli ada di disk dan developer perlu men-debug saat runtime.
Default Bundler Modern, Kebanyakan Orang Sudah Memiliki Minifier
Jika Anda menggunakan pipeline build modern, minifier Anda sudah berjalan. webpack 5 menggunakan terser-webpack-plugin dengan Terser secara default. Vite menggunakan esbuild untuk minifikasi secara default; Lightning CSS untuk CSS. Parcel menggunakan swc. Next.js beralih dari Terser ke swc di v12 (Oktober 2021), dan dari Babel ke swc untuk seluruh pipeline build di versi yang sama. Remix, Astro, SvelteKit, Nuxt, Rollup, esbuild standalone, semuanya menggabungkan minifikasi ke dalam build produksi tanpa intervensi developer. Hasilnya adalah bahwa bagi siapa saja yang menggunakan pipeline build modern, minifikasi JS terjadi secara otomatis dengan optimasi jauh melampaui apa yang dapat dilakukan alat regex file tunggal. Kasus di mana minifier di browser ini layak: halaman HTML yang dibuat dengan tangan dengan blok <script> inline; tema WordPress yang dikirim tanpa toolchain Node; generator situs statis yang tidak menggabungkan minifikasi; snippet sekali pakai yang ditempel di CMS atau template email; eksperimen cepat di mana menyiapkan pipeline build akan memakan waktu lebih lama daripada skrip itu sendiri.
Lingkup Jujur: Apa yang Dilakukan dan Tidak Dilakukan Alat Ini
Alat ini adalah minifier berbasis regex, sekitar 30 baris JavaScript. Ini menokenisasi literal string, template literal dan literal regex menjadi placeholder sehingga transformasi berikutnya tidak dapat merusak isinya; menghapus komentar // ... dan /* ... */; menciutkan rentetan spasi; menghapus spasi di sekitar tanda baca yang tidak membutuhkannya; dan mengembalikan literal yang ditokenisasi. Output tipikal adalah 20-40% lebih kecil dari input dalam byte mentah. Apa yang tidak dilakukan alat ini, dan yang minifier produksi (Terser, swc, esbuild, Closure) tangani: ia tidak mengganti nama variabel lokal menjadi huruf tunggal (tidak ada mangling sadar-scope); ia tidak melakukan eliminasi kode mati atau tree-shaking; ia tidak melakukan constant folding atau penyederhanaan ekspresi; ia tidak mengeluarkan source map; ia tidak memahami sintaks TypeScript (tempel hanya JavaScript polos); ia tidak tree-shake impor modul ES; ia tidak menulis ulang nama properti. Pembingkaian jujur: tempel JavaScript yang keluar dari editor Anda atau tangan Anda, dapatkan kembali versi yang dilucuti yang biasanya 20-40% lebih kecil dalam byte mentah, dan gunakan sebagai artefak quick-deploy. Untuk proyek yang memiliki pipeline build, gunakan Terser, swc atau esbuild dalam pipeline itu; optimasi sadar-AST adalah perbedaan antara pengurangan 20-40% alat ini dan 60-80% minifier produksi.
Jebakan Minifier Regex
Sebuah pass berbasis regex yang tidak memahami tata bahasa JavaScript dapat merusak kode dengan cara yang halus. Jebakan klasik: template literal menggunakan backtick dan dapat berisi ekspresi yang diinterpolasi (`Hello ${name}!`) yang terlihat seperti kandidat penghapusan komentar jika regex tidak hati-hati. Literal regex seperti /^\/\*/g berisi garis miring ke depan, urutan seperti komentar, dan konten seperti string; salah menangani mereka mengubah regex menjadi kode yang rusak secara sintaksis. String yang berisi teks seperti komentar (const url = "// example.com"), penghapusan komentar yang naif akan menghapus semuanya setelah //. Gotcha ASI, Automatic Semicolon Insertion adalah fitur JS yang memungkinkan Anda menghilangkan titik koma sebagian besar waktu, tetapi berinteraksi buruk dengan penghapusan spasi ketika token berikutnya dimulai dengan paren, tanda kurung, atau operator ((/regex/), [arr], +1), penciutan spasi yang ceroboh dapat mengubah "dua pernyataan" menjadi "satu pernyataan dengan kesalahan parsing". Mitigasi di alat ini adalah pass tokenisasi literal yang berjalan pertama, mengganti setiap string dan regex dengan placeholder unik, melakukan pekerjaan komentar+spasi pada kode yang dibersihkan, kemudian mengembalikan placeholder. Tidak sempurna, tetapi mencakup kasus umum. Jika Anda mencurigai minifier merusak kode Anda, hal pertama yang harus diperiksa adalah literal regex yang berisi urutan garis miring yang dilewatkan tokenizer.
Privasi: Mengapa Browser-Saja Penting di Sini
Minifier JS sisi server (alat online yang POST kode Anda ke server, menjalankannya melalui Terser di sana, dan mengembalikan hasilnya) memerlukan unggahan sumber Anda. Untuk kode pustaka biasa ini tidak berbahaya. Untuk alat internal, kode produk yang belum dirilis, JavaScript yang berisi kunci API inline atau kredensial layanan pihak ketiga, atau kode apa pun yang mengungkapkan algoritma kepemilikan atau logika bisnis, tidak. Minifier murni berbasis browser, JavaScript yang berjalan di tab Anda yang tidak pernah membuat permintaan jaringan setelah pemuatan halaman awal, menghindari masalah. Anda dapat memverifikasi dengan membuka tab Network DevTools, menempel kode, mengklik Minify, dan mengamati setiap permintaan yang keluar. Lebih baik lagi, putuskan sambungan dari internet (atau aktifkan mode pesawat) setelah halaman dimuat dan alat masih akan bekerja, yang merupakan bukti empiris terkuat bahwa tidak ada yang sedang diunggah.
Pertanyaan yang Sering Diajukan
Seberapa lebih kecil kode saya?
Untuk kode yang diformat dengan tangan dengan komentar dan indentasi, harapkan pengurangan ukuran 20-40% dalam byte mentah. Minifier produksi (Terser, swc, esbuild) dengan optimasi berbasis AST penuh mencapai 60-80%, kesenjangannya adalah penggantian nama simbol, eliminasi kode mati, dan constant folding, tidak satupun yang dapat dilakukan oleh alat regex-saja dengan aman. Setelah kompresi Brotli di edge CDN, penghematan tambahan dari minifikasi lebih sederhana (5-15% di luar Brotli pada asli yang tidak diminify) tetapi tidak nol, dan pada skala itu bertambah.
Apakah output yang diminify akan merusak kode saya?
Untuk sebagian besar kode, tidak. Kasus tepi yang diketahui adalah di sekitar literal regex dengan urutan garis miring (/foo\/bar/), template literal dengan interpolasi tersemat yang melintasi baris, dan konteks Automatic Semicolon Insertion di mana menghapus newline mengubah parse. Pass tokenisasi literal alat ini menangani kasus umum, tetapi jika kode Anda sangat berat di salah satu pola tersebut, uji output yang diminify di browser sebelum men-deploy. Untuk pipeline build produksi, gunakan Terser atau swc, mereka memiliki kesadaran AST penuh dan menangani kasus ini dengan benar.
Apakah alat ini mengganti nama variabel?
Tidak. Mangling variabel, mengubah function calculateTotal(itemList) menjadi function a(b), memerlukan analisis scope penuh pada AST untuk mengetahui nama mana yang aman diganti namanya. Pass regex tidak dapat melakukan ini dengan aman. Untuk penggantian nama simbol, gunakan Terser, UglifyJS atau swc dalam pipeline build; mereka mengimplementasikan mangling sadar-scope dengan benar. Pengurangan ukuran tambahan 10-25% yang dihasilkannya nyata dan layak dilakukan untuk kode produksi.
Bisakah saya menempel TypeScript?
Tidak, alat ini adalah minifier khusus JavaScript. TypeScript menambahkan anotasi tipe (function add(a: number, b: number): number), antarmuka, enum, dekorator dan sintaks lain yang bukan JavaScript valid. Kompilasi TypeScript Anda ke JavaScript terlebih dahulu menggunakan tsc, swc, esbuild atau Babel, kemudian tempel output JavaScript di sini. Sebagian besar proyek TypeScript sudah melalui salah satu kompiler tersebut sebagai bagian dari build, jadi JavaScript ada di suatu tempat.
Haruskah saya menggunakan ini jika sudah memiliki pipeline build?
Mungkin tidak, bundler Anda melakukan ini untuk Anda, dengan optimasi berbasis AST jauh melampaui apa yang dapat ditawarkan alat regex. webpack 5 mengirim terser-webpack-plugin dengan Terser; Vite menggunakan esbuild untuk JS secara default; Parcel menggunakan swc; Next.js telah menggunakan swc sejak v12 (Oktober 2021). Alat ini untuk kasus yang tidak dicakup pipeline build Anda: halaman HTML buatan tangan, tema WordPress yang dikirim tanpa toolchain Node, generator situs statis yang tidak menggabungkan minifikasi, snippet sekali pakai, atau eksperimen cepat di mana menyiapkan build akan memakan waktu lebih lama daripada skrip itu sendiri.
Apakah file saya diunggah?
Tidak. Minifier adalah JavaScript yang berjalan di browser Anda. Kode yang Anda tempel tidak pernah melintasi jaringan, verifikasi di tab Network DevTools saat Anda mengklik Minify, atau bawa halaman offline setelah dimuat dan konfirmasi alat masih bekerja. Alat internal, kode produk yang belum dirilis, skrip yang berisi kunci API inline atau logika bisnis kepemilikan tetap di perangkat Anda.
Alat terkait
Minifier CSS
Minifikasi CSS dengan menghapus komentar, spasi, dan karakter yang tidak perlu.
Minifier HTML
Minifikasi HTML dengan menghapus komentar, spasi, dan atribut opsional.
Pemformat & validator JSON
Format, minifikasi, dan validasi JSON seketika. Indentasi yang dapat dikonfigurasi dan pesan kesalahan.