Catatan kerja saya soal WP Rocket untuk satu situs memuat tabel penyimpanan cache. Baris used CSS, milik fitur Remove Unused CSS (RUCSS), menyebut datanya disimpan di tabel database {prefix}_wpr_rucss_used_css, dengan keterangan "no function exists in 3.21". Keterangan itu sempat terbaca sebagai "used CSS cuma bisa dibersihkan dengan tangan". Koreksinya bertanggal 29 Agustus 2026, dan isinya tegas: bacaan itu salah.
Tabelnya sendiri tidak berbohong. Fungsi rocket_clean_used_css() memang tidak ada. Yang keliru adalah lompatan dari "tidak ada fungsi" ke "harus dengan tangan", karena tombol Clear Used CSS di panel pun tidak memanggil fungsi. Tombol itu menembakkan filter, dan filter bisa di-apply dari WP-CLI. Jebakannya ada pada cara jalur ini gagal: tanpa --user, perintahnya membalas {"status":"die"}, tidak menghapus apa pun, dan tidak memberi tanda bahwa ada yang salah.
Tulisan lama saya soal RUCSS yang merusak menu mobile menyarankan menekan Clear Used CSS di panel setiap kali setting RUCSS diubah. Tulisan ini soal menjalankan pembersihan yang sama tanpa panel, dan soal beberapa hasil kosong di sekitarnya yang gampang dikira tanda beres.
Tombol itu ujungnya sebuah filter
Rantai dari tombol sampai penghapusan saya telusuri di WP Rocket 3.21.1, dan bentuknya begini:
admin_post_rocket_clean_saas
-> WP_Rocket\Engine\Saas\Admin\Subscriber::clean_saas
-> WP_Rocket\Engine\Saas\Admin\Clean::clean_saas
-> apply_filters( 'rocket_saas_clean_all', [] )
-> WP_Rocket\Engine\Optimization\RUCSS\Admin\Subscriber::truncateMata rantai yang penting adalah baris keempat. Pembersihannya digerakkan oleh filter rocket_saas_clean_all, dan filter bisa dijalankan dari kode mana saja, termasuk WP-CLI, tanpa lewat tombolnya. Nonce yang diperiksa di clean_saas() juga tidak perlu dipalsukan, karena nonce itu proteksi CSRF untuk request dari peramban, bukan bagian dari logika pembersihannya. Kalau versi WP Rocket-mu lain, telusuri ulang rantainya sebelum memercayai nama-nama di atas.
die yang terlihat seperti selesai
WP-CLI menjalankan WordPress tanpa user yang sedang login, kecuali kamu memberinya flag global --user. Untuk filter ini flag itu wajib, dan ketiadaannya tidak memberi tanda apa pun. Tanpa --user, panggilan yang sama membalas seperti ini:
wp eval 'echo wp_json_encode( apply_filters("rocket_saas_clean_all", []) );'
# {"status":"die"}Balasan itu tidak mengubah apa pun. Baris tabel dan berkasnya tetap persis di tempatnya. die di sini adalah pengecekan capability yang gagal, bukan error, sehingga run yang sama sekali tidak melakukan apa-apa terlihat seperti run yang selesai.
Dengan --user berisi ID user admin saya sendiri di situs itu, perintah yang sama membalas lain:
wp --user=<ADMIN_ID> eval 'echo wp_json_encode( apply_filters("rocket_saas_clean_all", []) );'
# {"status":"success","message":"<strong>WP Rocket</strong>: Used CSS cache cleared!"}wp_json_encode di situ hanya supaya array yang dikembalikan filter tercetak dan bisa dibaca. Yang perlu dicek adalah isinya: success dengan pesan, bukan die tanpa pesan.
Hitung kedua penyimpanan, sebelum dan sesudah
Karena die begitu gampang terlewat, aturan yang saya tetapkan untuk perintah ini sederhana: selalu hitung baris dan berkas sebelum dan sesudah menjalankannya. Filter itu mengosongkan dua penyimpanan sekaligus. Di situs itu, baris tabel used CSS turun dari 4.049 ke 0, dan berkas di wp-content/cache/used-css/ turun dari 711 ke 0.
Keduanya harus dihitung, karena mengukur dari isi kolom saja menipu. SUM(LENGTH(css)) terbaca 0 karena CSS-nya tinggal di berkas, bukan di kolom tabel. Versi sederhananya, dengan prefix tabel yang perlu kamu sesuaikan:
wp db query "SELECT COUNT(*) FROM wp_wpr_rucss_used_css"
find wp-content/cache/used-css -type f | wc -lTabelnya saya backup sebelum menjalankannya; dump-nya sekitar 1,2 MB. Sesudah used CSS kosong, baru page cache di-purge, dengan urutan itu. Alasannya ada di bagian berikutnya.
Hasil yang benar bisa terlihat seperti kerusakan. Setiap halaman kehilangan blok inline <style id="wpr-usedcss"> dan me-link stylesheet hasil kompilasi tema sebagai gantinya. Itu benar, bukan rusak. Halaman tanpa wpr-usedcss dan dengan link stylesheet sungguhan adalah keadaan antara yang sehat. Diukur di delapan URL, stylesheet tema ada di kedelapannya, dan homepage ter-gzip turun dari 54.859 ke 33.492 byte.
Baris used CSS dulu, page cache belakangan
rocket_clean_domain() tidak sekadar mengosongkan direktori. Fungsi itu memicu preload Rocket, yang langsung mulai meng-crawl dan meng-cache ulang halaman. Kalau page cache di-purge lebih dulu, preload memanggang used CSS lama ke HTML yang baru di-cache, dan baris yang kemudian kamu hapus adalah satu-satunya catatan yang akan menyuruh Rocket meregenerasinya. Hasilnya halaman ter-cache dengan <style id="wpr-usedcss"> basi, tanpa satu baris pun tersisa di tabel yang menjelaskan sebabnya.
Ini terukur di satu deploy yang menyentuh empat artikel. Satu class milik tema dan utilitas .border-y tidak ada di used CSS yang di-inline pada dua dari empat artikel, sementara SELECT ke tabel per URL tidak mengembalikan apa pun untuk satu pun dari mereka. Membalik urutannya dan memanaskan tiap halaman dua kali memperbaiki keempatnya. Halaman kembali dengan <link> sungguhan ke stylesheet tema, lalu Rocket meregenerasi used CSS yang benar dalam sekitar satu menit.
Urutan itu yang dipegang kode perbaikan di catatan yang sama. Versi sederhananya:
// baris used CSS DULU, urutan ini bukan kosmetik
$wpdb->query( $wpdb->prepare(
"DELETE FROM {$wpdb->prefix}wpr_rucss_used_css WHERE url = %s",
$url
) );
rocket_clean_domain(); // page cache, memicu preload
rocket_clean_minify();
rocket_clean_cache_busting();Panggilan rocket_clean_minify() di bawahnya sejalan dengan aturan di catatan yang sama: setelah perubahan CSS atau JS apa pun, page cache, aset minified, dan used CSS harus dibersihkan semuanya.
Pemeriksaan yang membuktikannya bukan "apakah class-nya ada di HTML". Class yang ada di markup tidak mengatakan apa pun soal apakah rule-nya dipertahankan. Yang dihitung adalah rule-nya di dalam <style id="wpr-usedcss">, dari HTML yang diambil langsung dari origin. Nama class dan stylesheet di bawah sudah saya ganti dengan nama netral:
curl -s --resolve host:443:<origin> https://host/url/ -o p.html
grep -o '\.article-body' p.html | wc -l # rule-nya, di dalam <style id="wpr-usedcss">
grep -c 'theme.css' p.html # 1 = RUCSS mati untuk halaman ini (CSS penuh, tidak apa-apa)Waspadai juga varian yang sah. Artikel tanpa pull quote memang seharusnya tidak punya .border-y, jadi periksa selector yang benar-benar dipakai halaman itu sebelum menyebut ketiadaannya sebagai bug.
Hapus per URL: kolom url tidak pakai garis miring
Membersihkan seluruh tabel ada harganya. Pada pass hardening plugin di hari yang sama dengan koreksi tadi, used CSS sengaja tidak saya sentuh: ada 4.046 baris, tidak ada CSS yang berubah, dan menghapusnya berarti meregenerasi semua halaman situs sekaligus.
Catatan yang sama menetapkan aturan untuk deploy: hapus used CSS hanya untuk URL yang berubah, bukan seluruh tabel. Waktu itu ada 3.863 baris, dan menghapus semuanya membuat setiap halaman situs beregenerasi sekaligus. Di kejadian tersebut, 47 baris mencakup 40 URL. Dua baris untuk satu URL itu normal: satu untuk desktop dan satu untuk is_mobile.
Jalur per URL ini punya angka nol sendiri yang menipu. Diukur 18 Agustus 2026, kolom url di tabel used CSS menyimpan https://example.com/hub, tidak pernah https://example.com/hub/, padahal setiap URL live situs itu memakai trailing slash dan home_url("/hub/") mengembalikan slash. Kueri LIKE '%/hub/' mencocokkan 0 dari 4.326 baris, dan angka nol itu terbaca persis seperti "halaman ini tidak punya baris used CSS". Kesimpulannya salah, dan akibatnya ikut salah: purge-nya dilewati.
Jangan juga mundur ke LIKE '%hub%'. Kueri itu mencocokkan 89 baris, karena 34 artikel anak tinggal di bawah prefix yang sama dan baris mereka tidak bermasalah. Yang dipakai hanya pencocokan persis, dengan URL yang dibuang slash-nya lebih dulu. Baris $t saya tambahkan supaya potongannya lengkap:
$t = $wpdb->prefix . 'wpr_rucss_used_css';
$bare = untrailingslashit( home_url( "/$slug/" ) ); // wajib
$wpdb->query( $wpdb->prepare( "DELETE FROM `$t` WHERE url = %s", $bare ) );Sebelum memercayai angka nol, lihat dulu isi kolomnya. SELECT url FROM $t LIMIT 6 menuntaskannya dalam satu kueri. Sesudah barisnya terhapus dan page cache di-purge, panaskan halamannya dua kali, karena hit pertama meregenerasi dan hit kedua menyajikannya, lalu ukur ulang.
Hasil kosong bukan bukti
Hampir setiap jebakan di sini berbentuk hasil kosong yang terbaca seperti "beres" atau "tidak ada yang perlu dikerjakan". {"status":"die"} terlihat seperti run yang selesai padahal tidak menghapus apa pun. SUM(LENGTH(css)) bernilai 0 walaupun CSS-nya masih ada di berkas. SELECT per URL yang kosong sesudah urutan purge terbalik tidak berarti halamannya bersih, dan LIKE '%/hub/' yang mencocokkan 0 dari 4.326 baris tidak berarti halamannya tidak punya used CSS.
Penangkalnya sama untuk semuanya: jalankan filternya dengan --user, hitung baris dan berkas di kedua sisi, hapus baris used CSS sebelum rocket_clean_domain(), dan lihat isi kolomnya sebelum memercayai angka nol.