Minifier CSS
Kompresi CSS dengan menghapus komentar dan spasi, dan mengoptimalkan nilai.
Tentang minifikasi CSS
Mengasumsikan bahwa karena Brotli mengompresi stream teks dengan sangat agresif, nilai marginal dari pass minifikasi terpisah telah runtuh. Blog teknik Sentry menjalankan argumen itu persis pada April 2024 dan menyimpulkan sebaliknya: minifikasi masih membayar. Dengan kecepatan internet mobile median global sekitar 53 Mbps dan Brotli yang dikerahkan secara universal di tepi CDN, "jika Anda dapat mencukur hanya 1 KB dari total 100 sumber daya pada setiap pemuatan halaman, Anda dapat membuat peningkatan 15 ms pada kecepatan halaman untuk pengguna tersebut." Dikalikan di seluruh basis pengunjung dari situs non-trivial mana pun, itu menjadi tagihan bandwidth yang nyata, biaya baterai yang nyata pada perangkat mobile, dan perubahan posisi yang nyata pada laporan Lighthouse.
Mekanismenya penting. Gzip dan Brotli adalah kompresor lossless tujuan-umum yang mencari urutan byte yang berulang dan mengkodekan setiap pengulangan sebagai back-reference ke kamus sliding-window. Dua file CSS yang menghasilkan perilaku browser yang sama tetapi mengandung byte yang berbeda akan terkompresi ke dua ukuran yang berbeda. margin: 10px 10px 10px 10px; dan margin:10px secara semantik identik, tetapi yang pertama memiliki lebih banyak karakter yang perlu dikodekan meskipun banyak yang merupakan pengulangan: Brotli pandai menemukan pengulangan tetapi tidak memahami bahwa dua string CSS yang berbeda secara sintaksis mengekspresikan aturan yang sama. Hanya minifier yang sadar-CSS yang dapat melakukan itu. Hub pembelajaran Cloudflare menempatkan pengurangan teks-mentah tipikal pada 30-50%; Brotli di atas menambahkan 5-15% sederhana lainnya, tetapi itu bukan nol, dan pada skala besar itu menumpuk.
CSS Adalah Render-Blocking: dan Itulah Mengapa Byte Penting
Largest Contentful Paint adalah salah satu dari tiga Core Web Vitals; ambang untuk "Baik" adalah 2,5 detik pada persentil ke-75 pemuatan halaman. Skor Performance Lighthouse keseluruhan menimbang LCP pada 25% dari total. CSS adalah render-blocking secara default: ketika browser melihat <link rel="stylesheet"> ia menjeda rendering hingga file diunduh dan CSSOM dibangun, karena aturan kemudian dalam stylesheet dapat mengganti aturan sebelumnya dan browser tidak dapat berisiko mengecat dalam keadaan tidak-distyled atau salah-distyled. CSS Object Model, tidak seperti DOM, tidak dibangun secara incremental: parser memerlukan seluruh stylesheet untuk mengetahui aturan mana yang menang. JavaScript juga memblokir di sini: skrip tidak dapat berjalan dengan aman saat CSSOM tidak lengkap. Implikasi praktisnya adalah setiap byte CSS render-blocking berada di jalur kritis dari setiap Core Web Vital. Bundel diminifikasi 100 KB menghemat Anda mungkin 30 ms pada link 4G cepat dibandingkan dengan yang tidak diminifikasi 150 KB: kecil per halaman, tetapi studi kasus Vodafone menunjukkan peningkatan penjualan 8% dari peningkatan LCP 31%. Efek urutan-kedua bahkan lebih besar: LCP yang lebih cepat menaikkan skor Lighthouse, yang menaikkan visibilitas pencarian Google untuk situs di mana Web Vitals adalah sinyal peringkat yang dikenal.
Apa yang Sebenarnya Dilakukan Minifier CSS
- Penghapusan spasi. Spasi, tab, dan baris baru yang ada hanya untuk keterbacaan manusia dilucuti. Spasi di dalam string (nama font-family, nilai konten, URL) dan spasi yang memisahkan token tetap:
1px solid redtidak dapat menjadi1pxsolidredkarena parser tidak akan lagi mengenali tiga nilai. - Penghapusan komentar. Blok
/* ... */dihapus. Konvensi yang dihormati secara luas adalah bahwa komentar yang dimulai dengan/*!diperlakukan sebagai penting: biasanya pemberitahuan hak cipta atau lisensi: dan dipertahankan oleh minifier produksi seperti cssnano, clean-css, lightningcss, dan esbuild. - Pengompresan unit-nol.
0px,0em,0%,0pt,0vwsemua dikurangi menjadi0, karena panjang nol adalah panjang yang sama terlepas dari unit. Kasus tepi yang hati-hati ("Not All Zeros are Equal" Miriam Suzanne, 2022): nol di dalamcalc(),min(),max(), danclamp(), dan di dalam properti custom CSS, tidak dapat dilucuti dengan aman karena aturan aritmetika-tipped CSS Values and Units Module Level 4 memerlukan unit untuk membedakan panjang dari angka.0sdalamtransitiontidak dapat menjadi0karena properti memerlukan nilai waktu. - Pemendekan warna hex. Warna hex enam-digit di mana setiap pasangan digit identik dapat ditulis sebagai tiga digit:
#FFFFFF → #FFF,#336699 → #369. Spesifikasi CSS Color mendefinisikan bentuk tiga-digit sebagai persis setara dan telah melakukannya sejak CSS1. - Penghapusan titik koma trailing. Titik koma antara deklarasi terakhir dalam blok aturan dan brace penutup adalah opsional, sehingga
color:red;}menjadicolor:red}. Satu byte per aturan, yang menumpuk. - Penurunan keyword ke huruf kecil. Keyword CSS adalah case-insensitive, sehingga
BLOCKdanblockberarti sama, tetapi huruf kecil mengompresi lebih baik dan ditokenisasi secara seragam. - Pengompresan shorthand.
margin: 10px 10px 10px 10pxmenjadimargin: 10px;margin: 10px 20px 10px 20pxmenjadimargin: 10px 20px. Minifier produksi tahu aturan shorthand untukmargin,padding,border,border-radius,background,font,transition,animation, dan keluarga grid.
Minifier vs Optimizer: Garis Aman-vs-Agresif
Dokumentasi cssnano membedakan antara preset "default"-nya (transformasi aman saja) dan preset "advanced"-nya (transformasi agresif yang bergantung pada asumsi tentang CSS Anda). Preset default adalah apa yang Anda hidupkan tanpa berpikir; preset advanced adalah apa yang Anda hidupkan setelah audit, karena beberapa optimasi dapat merusak kode yang bergantung pada perilaku cascade halus, prefiks vendor, atau keanehan browser. Transformasi advanced dapat mengurutkan ulang aturan dalam stylesheet untuk meningkatkan kompresibilitas: berisiko jika Anda memiliki fallback properti-duplikat yang disengaja seperti display: flex; display: grid;. Mereka dapat menggabungkan body aturan identik ke dalam daftar selektor yang dipisahkan koma. Mereka dapat menjatuhkan deklarasi yang ditimpa sebagai kode mati, dengan peringatan fallback yang sama. Mereka dapat menormalkan nilai display, fungsi transform, dan pengidentifikasi custom: translate3d(0,0,0) dapat disederhanakan menjadi translate(0) jika Anda tidak bergantung pada efek samping promosi-GPU. Mereka dapat menjatuhkan prefiks vendor yang tidak terpakai berdasarkan target Browserslist. csso (Yandex, 2011) menggambarkan dirinya sebagai "optimizer struktural" daripada minifier murni, dengan tiga kategori transformasi: pembersihan, kompresi, dan restrukturisasi. Lightning CSS menggambarkan pemisahan yang sama: pass "minify" yang selalu aman, ditambah set transformasi yang sadar-targets yang mengkompilasi CSS modern ke yang dipahami browser yang lebih lama. Garis jujur: minifier adalah apa yang dapat Anda terapkan ke file CSS apa pun tanpa berpikir; optimizer adalah apa yang Anda terapkan dengan pengetahuan tentang codebase Anda.
Sejarah Singkat Tooling Minifikasi CSS
YUI Compressor (2007). Julien Lecomte Yahoo mengumumkan YUI Compressor pada 11 Agustus 2007. Rilis asli hanya menangani JavaScript; tiga hari kemudian, versi 2.0 menambahkan dukungan CSS dengan mengintegrasikan minifier CSS berbasis-regex yang awalnya ditulis oleh Isaac Schlueter untuk penggunaan pribadi. YUI Compressor adalah standar de facto selama beberapa tahun, terutama di dunia Java/Maven dan pipeline-aset-Rails; itu masih digunakan hari ini, meskipun pustaka YUI itu sendiri pensiun oleh Yahoo pada 2014. Sisi CSS YUI Compressor selalu berbasis-regex, bukan berbasis-AST: keputusan desain yang konsekuensinya bergema di alat sisi-browser yang lebih kecil yang mengikuti.
clean-css (2011). Jakub Pawlowicz menerbitkan clean-css di bawah organisasi GoalSmashers di GitHub pada 2011, menyebutnya sebagai "optimizer CSS yang cepat dan efisien untuk Node.js dan Web." Itu adalah minifier CSS besar pertama yang dirancang khusus untuk ekosistem Node.js dan menjadi default di pipeline Grunt dan Gulp. Lini 5.x saat ini menarik sekitar 21 juta unduhan mingguan dari npm, mendukung inlining @import, rebasing URL, dan source map, dan memiliki model "level optimasi" berjenjang yang membuat pemisahan aman-vs-agresif eksplisit. csso (2011) berasal sebagai proyek internal Yandex, diterbitkan dengan hak cipta 2011 oleh Sergey Kryzhanovsky berdasarkan ide dari Vitaly Harisov. cssnano (April 2015) oleh Ben Briggs mengambil pendekatan berbeda: alih-alih satu minifier monolitik, cssnano adalah bundel yang dikurasi dari plugin PostCSS kecil (~30 di preset default). Itu menjadi minifier CSS dominan dalam ekosistem JavaScript sebagian besar karena komposabilitas ini dan karena PostCSS sendiri: framework Andrey Sitnik, pertama dirilis November 2013: menjadi substrat untuk begitu banyak hal lain (Autoprefixer, Stylelint, pipeline pemrosesan Tailwind). cssnano sekarang berada di versi 7.x dan merupakan minifier CSS default di css-minimizer-webpack-plugin webpack, di Next.js, dan di banyak default framework lainnya.
Minifier CSS esbuild (2020-2021). Evan Wallace, salah satu pendiri Figma, merilis esbuild sebagai "proyek hobi yang saya tulis selama liburan musim dingin 2019-2020." Ditulis dalam Go, esbuild 10-100× lebih cepat daripada bundler berbasis-JavaScript pada saat itu. Dukungan CSS matang sepanjang 2021; sekarang ada di mana-mana sebagai minifier yang mendasari di Vite, di tsup, di banyak template framework. Lightning CSS (2021/2022). Devon Govett, pencipta Parcel, mengumumkan Parcel CSS pada 2021: parser, transformer, bundler, dan minifier CSS yang ditulis dari awal dalam Rust. Pitch-nya adalah kecepatan (10-100× lebih cepat daripada incumbents berbasis-JS) plus kebenaran (parser CSS-spec-following yang nyata, bukan pencocokan pola regex) plus kompilasi yang sadar-targets (turunkan CSS modern ke yang dipahami browser yang lebih lama, seperti Babel untuk JavaScript). Pada 2022 proyek diganti namanya menjadi Lightning CSS untuk memisahkannya dari Parcel sebagai alat mandiri. Itu sekarang merupakan pipeline CSS modern yang direkomendasikan Vite, default di Parcel sendiri, dan opsi di css-minimizer-webpack-plugin. Mesin Oxide generasi-berikutnya Tailwind mengintegrasikannya.
Pipeline CSS Modern
Proyek web modern jarang menulis CSS mentah ke stylesheet. Sass (Hampton Catlin dan Natalie Weizenbaum, pertama dirilis 2006), Less (Alexis Sellier, 2009), dan Stylus (TJ Holowaychuk, 2010) duduk di depan pipeline, menambahkan variabel, penyarangan, mixin, fungsi, dan parsial. Compiler memancarkan CSS vanilla, yang kemudian mengalir melalui PostCSS untuk transformasi seperti Autoprefixer (penerapan prefiks-vendor berdasarkan Browserslist), unwrapping nested-CSS, dan penurunan-level CSS modern. Hanya setelah semua ini minifier berjalan, pada CSS datar akhir. Bundler modern mengirim minifikasi CSS secara default: webpack 5 menyertakan css-minimizer-webpack-plugin (cssnano di bawah kap secara default, dengan cssoMinify, cleanCssMinify, esbuildMinify, dan lightningCssMinify semua dapat dipilih); Vite menggunakan esbuild untuk CSS secara default dan mendukung Lightning CSS sebagai opt-in; Parcel menggunakan Lightning CSS; Next.js, Remix, Astro, SvelteKit, dan Nuxt semua membundel minifikasi ke dalam build produksi tanpa intervensi pengembang. Hasilnya adalah bahwa untuk siapa pun yang menggunakan pipeline build modern, minifikasi CSS terjadi secara otomatis.
Tetapi tidak semua orang menggunakan pipeline build. Banyak situs WordPress, halaman HTML buatan tangan, situs statis Jekyll/Hugo/Eleventy tanpa toolchain JS, dan proyek satu-kali mengirim CSS yang tidak pernah dekat dengan webpack. Untuk itu, minifier dalam-browser adalah jalur dengan paling sedikit hambatan: tempel CSS, salin hasilnya keluar, simpan deployment.
CSS Kritis
Teknik komplementer yang layak diketahui: CSS kritis adalah praktik mengidentifikasi subset style yang diperlukan untuk merender viewport above-the-fold, menyertakan subset itu langsung ke dalam blok <style> di head dokumen, dan menunda sisa stylesheet ke pemuatan non-blocking. Dilakukan dengan baik, halaman mengecat viewport awalnya pada round trip jaringan pertama, tanpa permintaan terpisah untuk stylesheet eksternal sama sekali. Filament Group membangun tooling kanonis: Scott Jehl menerbitkan loadCSS pada 14 Juli 2014, utility JavaScript kecil yang memuat stylesheet secara asinkron dengan mengatur atribut media-nya ke nilai non-cocok, kemudian menukarnya kembali ke all setelah file diunduh. Pola itu akhirnya menjadi cukup standar sehingga browser menambahkan <link rel="preload" as="style" onload="this.rel='stylesheet'"> sebagai cara yang lebih langsung untuk mengekspresikannya. Jason Miller (pencipta Preact) merilis Critters di bawah GoogleChromeLabs pada 2018 sebagai alternatif yang lebih cepat: alih-alih menjalankan browser headless untuk memeriksa halaman yang dirender, Critters melakukan analisis statis. Repositori Critters diarsipkan pada 2024 dengan fork yang dipelihara secara aktif sekarang hidup sebagai Beasties di bawah tim Nuxt. Semua alat ini bergantung pada CSS yang mendasarinya yang diminifikasi dengan baik: setiap byte yang disimpan di stylesheet sumber mengalir ke inline kritis yang lebih kecil.
Hack Legacy Telah Hilang
Semua browser modern mengurai CSS ke spesifikasi yang sama. Hack historis yang pernah membuat minifikasi CSS berisiko pada dasarnya hilang: hack * html menargetkan IE6 dengan mengeksploitasi bug parser; hack underscore _property: value menargetkan IE6 dan di bawahnya; *property: value (dengan * sebelum nama properti) menargetkan IE7 dan di bawahnya; komentar bersyarat <!--[if IE 6]> memungkinkan Anda menyajikan stylesheet yang berbeda untuk versi IE tertentu, tetapi Microsoft menghapus fitur ini di IE10. IE11 mencapai akhir-masa-pakai pada 15 Juni 2022 untuk sebagian besar versi konsumen Windows 10. Pada 2026 hack-hack ini adalah keingintahuan sejarah dan minifier CSS tidak perlu memikirkannya lagi. Minifier modern yang melucuti spasi secara identik di seluruh browser dan menerapkan transformasi yang ditentukan-spec yang dijelaskan di atas adalah aman.
Apa yang Dilakukan (dan Tidak Dilakukan) Alat Ini
Alat ini adalah minifier dalam-browser file-tunggal: sekitar 30 baris JavaScript. Ia tokenisasi literal string ke placeholder sehingga pass berikutnya tidak dapat merusak konten mereka, menghapus komentar /* ... */, mengompresi spasi di sekitar {, }, :, ;, ,, >, ~, +, menghapus titik koma trailing sebelum }, mengompresi run spasi menjadi spasi tunggal, memendekkan warna hex enam-digit ke bentuk tiga-digit ketika setiap pasangan digit identik, dan melucuti unit dari nilai nol untuk px, em, rem, %, pt, ex, ch, vw, vh, vmin, vmax. Itu tidak mengurai CSS ke AST: itu adalah pass regex. Itu tidak mengompresi longhand ke shorthand. Itu tidak menggabungkan atau mende-duplikat selektor. Itu tidak mengurutkan ulang deklarasi. Itu tidak mengonversi rgb() ke hex atau warna bernama ke hex. Itu tidak menurunkan keyword ke huruf kecil. Itu tidak mempertahankan komentar /*! penting: semua komentar dilucuti secara setara; jika Anda memiliki header lisensi untuk dipertahankan, tempel kembali setelah minifikasi. Itu tidak memancarkan source map. Framing yang jujur: tempel CSS 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 situs yang dibangun-tangan. Untuk proyek dengan pipeline build, gunakan cssnano atau Lightning CSS dalam pipeline itu; untuk yang tidak, alat ini menghilangkan friksi.
Mengapa Hanya-Browser Penting di Sini
Setiap minifier CSS berbasis-web memiliki pilihan arsitektural yang sama: melakukan pekerjaan di server, atau melakukannya di browser pengguna. Pemrosesan sisi-server memerlukan upload stylesheet melalui jaringan, yang berarti salinan CSS itu berada di log server, mungkin di cache CDN, mungkin di pipeline analytics, mungkin di backup. Untuk sebagian besar CSS ini tidak berbahaya. Untuk alat internal, style produk yang belum dirilis, atau stylesheet yang berisi selektor yang mengungkapkan taksonomi kelas internal (.admin-panel-internal-debug-info), tidak. Bahkan untuk CSS situs marketing biasa, pengembang yang mengaudit apa yang sebenarnya mereka kirim melintasi jaringan mungkin secara wajar lebih memilih bahwa work-in-progress tetap di mesin mereka. Minifier murni-berbasis-browser: JavaScript yang berjalan di tab Anda dan tidak pernah membuat permintaan jaringan setelah pemuatan halaman awal: melewati masalah. Anda dapat memverifikasi ini: buka tab Network DevTools, tempel CSS, klik Minify, dan tonton untuk permintaan keluar. Tidak akan ada. Lebih baik lagi, lepaskan koneksi dari internet (atau aktifkan mode pesawat) setelah halaman dimuat dan alat masih akan berfungsi, yang merupakan bukti empiris terkuat bahwa tidak ada yang diunggah.
Pertanyaan yang Sering Diajukan
Berapa banyak CSS saya akan menjadi lebih kecil?
CSS yang diformat tangan dengan komentar dan indentasi biasanya menyusut 20-40% dalam byte mentah. CSS yang sudah dikompilasi dari Sass/Less dan diformat ringan menyusut lebih sedikit. CSS yang telah diproses melalui PostCSS atau Autoprefixer sering kali sudah memiliki komentar minimal dan menyusut paling sedikit. Ukuran setelah kompresi Brotli di tepi CDN akan menyempit lebih lanjut: Brotli pada CSS yang diminifikasi masih menghemat 5-15% lainnya dibandingkan Brotli pada CSS yang tidak diminifikasi, tergantung pada seberapa berulang spasi asli.
Apakah output yang diminifikasi akan merusak sesuatu?
Untuk CSS biasa, tidak: transformasi aman-spec. Dua kasus yang layak diperiksa sendiri: (1) nilai nol di dalam calc(), min(), max(), clamp(), dan properti custom CSS tidak boleh unit-stripped karena aturan aritmetika-tipped memerlukan unit; pass regex alat ini konservatif tetapi jika Anda memiliki calc(0px + 10%) di CSS Anda, lihat output. (2) Jika stylesheet Anda memiliki fallback properti-duplikat seperti display: flex; display: grid;, alat ini mempertahankan keduanya: tetapi minifier advanced seperti cssnano dengan preset advanced akan menghapus yang pertama. Jika Anda bergantung pada perilaku cascade khusus-browser, audit sebelum men-deploy.
Apakah itu mempertahankan header lisensi?
Tidak. Minifier produksi menghormati konvensi bahwa komentar yang dimulai dengan /*! (dengan tanda seru) dipertahankan sebagai "penting": biasanya untuk header hak cipta dan pemberitahuan lisensi. Alat ini melucuti semua komentar secara setara. Jika Anda mengirim CSS yang membutuhkan header lisensi (atribusi sumber MIT, GPL, BSD), tempel header kembali ke output secara manual. Untuk pipeline yang membutuhkan preservasi otomatis, gunakan cssnano atau Lightning CSS sebagai gantinya.
Haruskah saya menggunakan ini jika saya sudah memiliki pipeline build?
Mungkin tidak: bundler Anda melakukan ini untuk Anda. webpack 5 mengirim css-minimizer-webpack-plugin dengan cssnano di bawah kap; Vite menggunakan esbuild untuk minifikasi CSS secara default; Parcel menggunakan Lightning CSS. Alat ini adalah untuk kasus yang tidak dicakup pipeline build Anda: HTML buatan tangan, tema WordPress yang dikirim tanpa toolchain Node, generator situs statis yang tidak membundel minifikasi, file CSS satu-kali untuk template email atau demo cepat. Untuk itu, alat browser tempel-masuk adalah jalur dengan paling sedikit hambatan.
Apakah file saya diunggah?
Tidak. Minifier adalah JavaScript yang berjalan di browser Anda. CSS 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 berfungsi. Stylesheet internal, style produk yang belum dirilis, dan CSS yang mengungkapkan taksonomi kelas internal tetap di perangkat Anda.
Bisakah saya unminify output nanti?
Tidak persis: komentar dan spasi asli hilang selamanya, itulah maksudnya. Tetapi Anda dapat memformat CSS yang diminifikasi untuk membuatnya dapat dibaca lagi. Pretty-printer seperti Prettier (dengan plugin CSS), perintah Format Document built-in di VS Code, atau salah satu alat "CSS beautifier" online akan menyisipkan kembali indentasi dan jeda baris. Mereka tidak dapat memulihkan komentar yang dihapus. Selalu simpan sumber yang tidak diminifikasi di kontrol versi sebagai bentuk kanonis.
Alat terkait
Minifier HTML
Minifikasi HTML dengan menghapus komentar, spasi, dan atribut opsional.
Minifier JavaScript
Minifikasi JavaScript dengan menghapus komentar dan spasi untuk mengurangi ukuran.
Pengoptimal SVG
Optimalkan dan minifikasi file SVG dengan menghapus komentar, metadata, dan spasi yang tidak perlu.