max-age mengatur berapa lama sebuah respons boleh dipakai ulang oleh cache mana pun, sedangkan s-maxage hanya berlaku untuk cache bersama seperti CDN dan proxy, dan nilainya menimpa max-age untuk cache jenis itu. Keduanya didefinisikan di RFC 9111, yaitu max-age pada bagian 5.2.1.1 untuk respons dan bagian 5.2.2.1 untuk permintaan, sementara s-maxage ada di bagian 5.2.2.10. Memahami pembagian itu penting karena satu nilai yang sama tidak bisa berlaku untuk browser pribadi dan CDN publik sekaligus.
Bagi situs yang melayani pembaca di banyak kota, salah pasang header caching berarti dua kerugian sekaligus: aset diunduh berulang kali sehingga lambat, atau halaman basi tertahan di CDN sehingga koreksi konten tidak sampai ke pembaca. Artikel ini memetakan direktif yang sering dipakai, pasangan yang berbahaya, dan cara membuktikan header benar-benar bekerja.
TL;DR
- max-age berlaku untuk semua cache; s-maxage hanya untuk cache bersama dan menimpanya.
- Validasi bersyarat dengan ETag dan If-None-Match menghasilkan 304 tanpa mengirim ulang isi.
- no-store bukan pengganti private; keduanya menutup jalur berbeda.
- Aset ber-hash di nama berkas paling aman diberi masa simpan panjang.
- Bukti header bekerja didapat dari curl, bukan dari asumsi konfigurasi server.
Apa bedanya max-age dan s-maxage?
max-age menentukan masa segar sebuah respons dalam satuan detik dan berlaku untuk seluruh cache, termasuk cache pribadi di browser. s-maxage hanya berlaku untuk cache bersama, dan bila keduanya muncul bersamaan, nilai s-maxage yang dipakai oleh cache bersama. Itu sebabnya satu halaman bisa disimpan lama di browser pengguna tetapi diperbarui lebih cepat di CDN, hanya dengan menuliskan dua nilai berbeda pada satu header.
Perbedaan ini kerap disalahartikan sebagai pengaturan kecepatan. Yang diatur sebenarnya adalah kebijakan penyimpanan: berapa lama salinan boleh dipakai tanpa bertanya ke server. Semakin panjang, semakin sedikit permintaan yang mencapai origin, dan semakin besar jarak antara perubahan di server dengan perubahan yang dilihat pembaca.
RFC 9111 yang mengatur caching HTTP menyebut max-age sebagai direktif respons pada bagian 5.2.1.1 dan sebagai direktif permintaan pada bagian 5.2.2.1, sementara s-maxage diatur pada bagian 5.2.2.10. Teks lengkapnya tersedia di RFC 9111 di rfc-editor.org.
| Jenis cache | Direktif yang dipatuhi | Contoh penerapan |
|---|---|---|
| Cache pribadi (browser) | max-age, no-store, private | Halaman akun, respons yang mengandung data pengguna |
| Cache bersama (CDN, proxy) | s-maxage bila ada, jika tidak max-age | Aset statis, halaman publik, gambar |
| Tanpa cache | no-store | Respons bertoken, halaman transaksi |
Kapan 304 Not Modified lebih hemat daripada 200?
Ketika cache sudah punya salinan tetapi masa segarnya habis, ia tidak harus mengunduh ulang seluruh isi. Dengan ETag, cache mengirim If-None-Match berisi penanda versi yang dimilikinya; bila penanda itu masih cocok, server membalas 304 tanpa badan respons. Hasilnya penghematan bandwidth pada isi yang tidak berubah, meski tetap ada satu perjalanan bolak-balik ke server.
Perilaku validasi ini dijelaskan di RFC 9110 yang mengatur semantik HTTP, termasuk ETag dan If-None-Match. Tautan resminya ada di RFC 9110 di rfc-editor.org. Untuk aset statis, ETag yang dihitung dari isi berkas biasanya cukup; untuk respons dinamis, ETag harus berubah setiap kali isi berubah, dan nilai yang salah lebih berbahaya daripada tidak ada ETag sama sekali karena pembaca bisa menerima versi lama tanpa batas.
Ada satu jebakan operasional: ETag yang dihitung dari metadata berkas, bukan dari isinya, bisa berubah ketika berkas disalin antar server. Gejalanya halus, yaitu cache terus meminta ulang karena penanda tidak cocok padahal isi sama. Menghitung dari isi membuat penanda stabil di semua replika.
Direktif mana yang berbahaya bila salah pasang?
Direktif berbahaya bukan yang salah tulis, melainkan yang benar tulis tetapi salah konteks. Tiga contoh yang paling sering menimbulkan insiden adalah no-store yang dipasang global sehingga aset statis ikut tidak pernah tersimpan, private yang dipasang pada halaman publik sehingga CDN tidak bisa menolong sama sekali, dan masa simpan panjang pada HTML yang isinya berubah tanpa penanda versi di nama berkas.
Kombinasi terakhir paling sering terjadi di situs yang baru berpindah ke CDN. HTML diberi masa simpan satu tahun agar skor performa terlihat bagus, lalu koreksi konten tidak muncul di peramban pembaca. Cara keluarnya bukan menghapus CDN, melainkan memisahkan kebijakan: HTML berumur pendek, aset yang namanya mengandung hash berumur panjang.
Untuk direktif yang tidak disebut di sini, rujukan ringkas yang enak dipakai saat menulis konfigurasi adalah dokumentasi Cache-Control di MDN. Dokumentasi itu memetakan direktif ke perilakunya, meski teks normatifnya tetap ada di RFC.
Bagaimana menyusun kebijakan per jenis aset?
Kebijakan yang berhasil biasanya memisahkan aset berdasarkan apakah namanya berubah ketika isinya berubah. Berkas yang namanya mengandung hash isi aman disimpan lama karena versi baru selalu punya nama baru; berkas yang namanya tetap harus disimpan pendek atau divalidasi setiap kali.
| Jenis aset | Pola kebijakan | Alasan |
|---|---|---|
| JS dan CSS ber-hash | Masa simpan panjang, tanpa validasi berkala | Nama berkas berganti setiap isi berubah |
| Gambar produk | Masa simpan sedang, validasi dengan ETag | Isi jarang berubah, nama cenderung tetap |
| HTML halaman publik | Masa simpan pendek, cache bersama boleh menyimpan | Isi berubah setiap penerbitan |
| Respons API publik | Masa simpan sangat pendek atau tanpa penyimpanan | Data cepat berubah, kesalahan mahal |
| Respons terautentikasi | Tanpa penyimpanan | Isi bergantung pengguna, tidak boleh dibagi |
Angka konkretnya bergantung pada ritme penerbitan dan tidak ada nilai universal. Yang bisa dipertanggungjawabkan adalah aturannya: semakin cepat isi berubah, semakin pendek masa simpan, dan semakin unik nama berkasnya, semakin panjang masa simpan yang aman.
Bagaimana membuktikan header benar-benar bekerja?
Periksa header dari server dengan permintaan langsung, lalu periksa perilaku validasi dengan mengirim penanda versi. Kalau respons pertama memuat ETag dan respons kedua dengan If-None-Match mengembalikan 304, rantai validasi bekerja. Kalau respons kedua tetap 200 dengan badan penuh, ada lapisan yang membuang header atau menimpanya.
curl -sI https://contoh.tld/aset.js | grep -i -E "cache-control|etag|age"
curl -sI -H "If-None-Match: "penanda"" https://contoh.tld/aset.js | head -1
Langkah kedua yang sering terlewat adalah memeriksa dari sisi cache bersama, bukan hanya dari sisi origin. Header Age pada respons menunjukkan bahwa salinan berasal dari cache, dan nilai Age yang terus bertambah membuktikan cache bekerja sesuai masa simpan yang ditetapkan. Tanpa pemeriksaan ini, konfigurasi yang tampak benar di origin bisa tidak berpengaruh sama sekali di CDN.
Kebiasaan terakhir yang layak diadopsi: catat pasangan header untuk tiap jenis aset di satu berkas konfigurasi, lalu tinjau berkas itu setiap kali ada laporan "konten tidak berubah". Sebagian besar laporan semacam itu selesai dengan membaca kebijakan yang tertulis, bukan dengan menebak dari perilaku peramban.
Bagaimana caching memengaruhi kunjungan pertama dan kedua?
Pada kunjungan pertama, cache belum punya salinan sehingga semua berkas diunduh dari server atau CDN. Manfaat kebijakan caching baru terasa pada kunjungan berikutnya, ketika aset yang belum kedaluwarsa dipakai langsung dari salinan lokal tanpa permintaan jaringan. Karena itu, pengukuran yang hanya memakai satu kali muat ulang di peramban yang sudah pernah membuka situs akan melebih-lebihkan kecepatan yang dirasakan pengunjung baru.
Implikasi praktisnya ada dua. Pertama, ukur dua kondisi secara terpisah dan catat keduanya, karena keduanya menjawab pertanyaan berbeda. Kedua, prioritaskan jumlah byte yang harus diunduh pada kunjungan pertama, sebab di situlah kebijakan caching tidak menolong sama sekali.
Untuk pembaca dengan koneksi lambat, kunjungan pertama adalah pengalaman yang menentukan, dan di situlah seluruh biaya unduhan awal jatuh. Memindahkan beberapa berkas kritis ke awal dokumen, atau mengurangi jumlah berkas yang harus diunduh sebelum halaman bisa dibaca, biasanya memberi dampak lebih besar daripada memperpanjang masa simpan berkas yang toh belum tersimpan.
Kapan perlu memaksa peramban mengambil versi baru?
Memaksa muat ulang sebaiknya menjadi pengecualian, bukan kebiasaan. Cara yang lebih sehat adalah memastikan setiap perubahan aset menghasilkan nama berkas baru, sehingga versi lama dan versi baru bisa hidup berdampingan di cache tanpa saling menimpa. Ketika nama berubah, tidak ada yang perlu dipaksa.
Jika nama berkas tidak bisa diubah, jalur yang tersisa adalah memperpendek masa simpan dan mengandalkan validasi bersyarat. Keduanya lebih lambat daripada mengganti nama berkas, tetapi jauh lebih dapat diprediksi daripada mengirim instruksi kepada pembaca untuk menekan tombol muat ulang paksa. Instruksi semacam itu tidak bisa diverifikasi, tidak berskala, dan menutupi masalah kebijakan yang sebenarnya.
Satu pemeriksaan yang berguna sebelum menerbitkan versi baru: pastikan berkas HTML yang merujuk aset baru memang tidak tersimpan lama di cache bersama. Kesalahan yang paling mahal bukan aset baru yang lambat tersedia, melainkan HTML lama yang terus merujuk aset lama meski aset baru sudah siap di server.
FAQ
Apakah s-maxage berlaku di browser?
Tidak. s-maxage hanya ditujukan untuk cache bersama seperti CDN dan proxy. Browser mengabaikannya dan memakai max-age, sehingga halaman bisa punya masa simpan berbeda di kedua jenis cache tanpa konflik.
Apakah no-store sama dengan no-cache?
Tidak. no-store melarang penyimpanan salinan sama sekali, sedangkan no-cache mengizinkan penyimpanan tetapi mewajibkan validasi ulang sebelum dipakai. Untuk respons yang mengandung data sensitif, no-store adalah pilihan yang tepat.
Apakah ETag wajib ada pada setiap respons?
Tidak wajib, tetapi sangat membantu untuk isi yang jarang berubah. Tanpa ETag, cache harus mengunduh ulang seluruh isi ketika masa segar habis, meski isinya identik dengan salinan yang sudah dimiliki.
Mengapa header sudah benar tetapi CDN tetap menyajikan versi lama?
Kemungkinan ada aturan di lapisan CDN yang menimpa header origin, atau ada purging yang belum dijalankan. Periksa header yang diterima klien, bukan hanya yang dikirim origin, dan bandingkan nilai Age pada respons.
Berapa lama masa simpan yang aman untuk HTML?
Belum ada angka universal, karena bergantung pada ritme penerbitan. Yang dapat dipertanggungjawabkan adalah membatasi masa simpan HTML lebih pendek daripada aset ber-hash, dan menambahkan validasi agar koreksi cepat sampai ke pembaca.
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬