Mencegah permintaan jaringan yang tidak perlu dengan Cache HTTP

Mengambil resource melalui jaringan akan berjalan lambat dan mahal:

  • Respons yang besar memerlukan banyak bolak-balik antara browser dan server.
  • Halaman Anda tidak akan dimuat sampai semua resource pentingnya telah didownload sepenuhnya.
  • Jika seseorang mengakses situs Anda dengan paket data seluler terbatas, setiap permintaan jaringan yang tidak perlu akan sia-sia.

Bagaimana Anda dapat menghindari permintaan jaringan yang tidak perlu? Cache HTTP browser adalah baris pertahanan pertama Anda. Cara ini belum tentu merupakan pendekatan yang paling andal atau fleksibel, dan Anda memiliki kontrol terbatas atas masa aktif respons yang di-cache, tetapi cara ini efektif karena didukung di semua browser, dan tidak membutuhkan banyak pekerjaan.

Panduan ini menunjukkan dasar-dasar implementasi cache HTTP yang efektif.

Kompatibilitas browser

Sebenarnya tidak ada API tunggal yang disebut Cache HTTP. Ini adalah nama umum untuk kumpulan API platform web. API ini didukung di semua browser:

Cara kerja Cache HTTP

Semua permintaan HTTP yang dibuat browser akan dirutekan terlebih dahulu ke cache browser untuk memeriksa apakah ada respons cache valid yang dapat digunakan untuk memenuhi permintaan tersebut. Jika ada kecocokan, respons akan dibaca dari cache, yang menghilangkan latensi jaringan dan biaya data yang ditimbulkan oleh transfer.

Perilaku Cache HTTP dikontrol oleh kombinasi header permintaan dan header respons. Dalam skenario ideal, Anda akan memiliki kontrol atas kode untuk aplikasi web Anda (yang akan menentukan header permintaan) dan konfigurasi server web Anda (yang akan menentukan header respons).

Lihat artikel HTTP Caching MDN untuk ringkasan konseptual yang lebih mendalam.

Permintaan {i>header<i}: tetap gunakan nilai {i>default<i} (biasanya)

Meskipun ada sejumlah header penting yang harus disertakan dalam permintaan keluar aplikasi web Anda, browser hampir selalu menangani setelannya atas nama Anda saat membuat permintaan. Header permintaan yang memengaruhi pemeriksaan keaktualan, seperti If-None-Match dan If-Modified-Since hanya muncul berdasarkan pemahaman browser tentang nilai saat ini di Cache HTTP.

Ini merupakan kabar baik—artinya Anda dapat terus menyertakan tag seperti <img src="my-image.png"> di HTML Anda, dan browser akan otomatis menangani cache HTTP untuk Anda, tanpa upaya tambahan.

Header respons: mengonfigurasi server web

Bagian dari penyiapan cache HTTP yang paling penting adalah header yang ditambahkan server web Anda ke setiap respons keluar. Semua header berikut diperhitungkan ke dalam perilaku caching yang efektif:

  • Cache-Control. Server dapat menampilkan perintah Cache-Control untuk menentukan cara dan durasi browser dan cache perantara lainnya meng-cache respons individual.
  • ETag. Saat menemukan respons cache yang sudah tidak berlaku, browser dapat mengirim token kecil (biasanya hash konten file) ke server untuk memeriksa apakah file telah berubah. Jika server menampilkan token yang sama, maka file tersebut sama, dan tidak perlu mendownload ulang.
  • Last-Modified. Header ini memiliki tujuan yang sama seperti ETag, tetapi menggunakan strategi berbasis waktu untuk menentukan apakah resource telah berubah atau tidak, dibandingkan dengan strategi berbasis konten ETag.

Beberapa server web memiliki dukungan bawaan untuk menyetel header tersebut secara default, sementara server lain tidak menyertakan header sepenuhnya kecuali jika Anda mengonfigurasinya secara eksplisit. Detail spesifik tentang cara mengonfigurasi header sangat bervariasi, bergantung pada server web yang Anda gunakan, dan Anda harus membaca dokumentasi server untuk mendapatkan detail yang paling akurat.

Untuk menghemat penelusuran, berikut petunjuk cara mengonfigurasi beberapa server web populer:

Membiarkan header respons Cache-Control tidak akan menonaktifkan penyimpanan HTTP ke cache. Sebagai gantinya, browser secara efektif menebak jenis perilaku caching yang paling sesuai untuk jenis konten tertentu. Kemungkinan Anda menginginkan lebih banyak kontrol daripada yang ditawarkan, jadi luangkan waktu untuk mengonfigurasi header respons Anda.

Nilai header respons mana yang harus Anda gunakan?

Ada dua skenario penting yang harus Anda bahas saat mengonfigurasi header respons server web.

Penyimpanan cache yang tahan lama untuk URL berversi

Cara URL berversi dapat membantu strategi penyimpanan dalam cache
URL dengan versi merupakan praktik yang baik karena memudahkan pembatalan respons yang di-cache.

Misalkan server Anda memerintahkan browser untuk menyimpan file CSS ke dalam cache selama 1 tahun (Cache-Control: max-age=31536000), tetapi desainer Anda baru saja membuat update darurat yang harus segera diluncurkan. Bagaimana cara memberi tahu browser untuk memperbarui salinan file yang di-cache yang "tidak berlaku"? Anda tidak dapat melakukannya, setidaknya tanpa mengubah URL sumber daya. Setelah browser meng-cache respons, versi yang di-cache akan digunakan hingga tidak lagi baru, sebagaimana ditentukan oleh max-age atau expires, atau sampai dikeluarkan dari cache karena beberapa alasan lain—misalnya, pengguna menghapus cache browser mereka. Akibatnya, pengguna yang berbeda mungkin akan menggunakan versi file yang berbeda ketika halaman dibuat: pengguna yang baru saja mengambil resource akan menggunakan versi baru, sementara pengguna yang meng-cache salinan sebelumnya (tetapi masih valid) akan menggunakan versi yang lebih lama dari responsnya. Bagaimana Anda bisa mendapatkan yang terbaik dari kedua hal tersebut: caching sisi klien dan update cepat? Anda dapat mengubah URL resource dan memaksa pengguna mendownload respons baru setiap kali kontennya berubah. Biasanya, Anda melakukannya dengan menyematkan sidik jari file, atau nomor versi, dalam nama filenya—misalnya, style.x234dff.css.

Saat merespons permintaan untuk URL yang berisi "sidik jari" atau informasi pembuatan versi, dan yang kontennya tidak pernah dimaksudkan untuk diubah, tambahkan Cache-Control: max-age=31536000 ke respons Anda.

Menyetel nilai ini akan memberi tahu browser bahwa saat perlu memuat URL yang sama kapan saja selama satu tahun ke depan (31.536.000 detik; nilai maksimum yang didukung), browser dapat langsung menggunakan nilai dalam Cache HTTP, tanpa harus membuat permintaan jaringan ke server web Anda sama sekali. Bagus—Anda sudah segera mendapatkan keandalan dan kecepatan yang dapat diperoleh dengan menghindari jaringan.

Alat build seperti webpack dapat mengotomatiskan proses penetapan sidik jari hash ke URL aset Anda.

Validasi ulang server untuk URL tanpa versi

Sayangnya, tidak semua URL yang Anda muat memiliki versi. Mungkin Anda tidak dapat menyertakan langkah build sebelum men-deploy aplikasi web, sehingga Anda tidak dapat menambahkan hash ke URL aset. Dan setiap aplikasi web memerlukan file HTML. File-file tersebut (hampir) tidak akan menyertakan informasi pembuatan versi, karena tidak ada yang akan terganggu untuk menggunakan aplikasi web Anda jika mereka perlu mengingat bahwa URL yang akan dikunjungi adalah https://example.com/index.34def12.html. Jadi, apa yang dapat Anda lakukan untuk URL tersebut?

Ini adalah salah satu skenario di mana Anda perlu mengaku kalah. {i>Cache<i} HTTP saja tidak cukup kuat untuk menghindari jaringan sepenuhnya. (Jangan khawatir—Anda akan segera mempelajari pekerja layanan, yang akan memberikan dukungan yang kami butuhkan untuk bertempur kembali demi kepentingan Anda.) Namun, ada beberapa langkah yang dapat Anda lakukan untuk memastikan permintaan jaringan secepat dan seefisien mungkin.

Nilai Cache-Control berikut dapat membantu Anda menyesuaikan lokasi dan cara URL tanpa versi di-cache:

  • no-cache. Hal ini akan memberi tahu browser agar memvalidasi ulang dengan server setiap saat sebelum menggunakan versi URL yang di-cache.
  • no-store. Kode ini menginstruksikan browser dan cache perantara lainnya (seperti CDN) untuk tidak pernah menyimpan versi file apa pun.
  • private. Browser dapat meng-cache file, tetapi cache perantara tidak dapat melakukannya.
  • public. Respons dapat disimpan oleh cache apa pun.

Lihat Lampiran: diagram alir Cache-Control untuk memvisualisasikan proses penentuan nilai Cache-Control mana yang akan digunakan. Perhatikan juga bahwa Cache-Control dapat menerima daftar perintah yang dipisahkan koma. Lihat Lampiran: contoh Cache-Control.

Selain itu, menyetel salah satu dari dua header respons tambahan juga dapat membantu: ETag atau Last-Modified. Seperti yang disebutkan dalam Header respons, ETag dan Last-Modified memiliki tujuan yang sama: menentukan apakah browser harus mendownload ulang file cache yang telah habis masa berlakunya. ETag adalah pendekatan yang direkomendasikan karena lebih akurat.

Contoh ETag

Asumsikan bahwa 120 detik telah berlalu sejak pengambilan awal dan browser telah memulai permintaan baru untuk resource yang sama. Pertama-tama, browser akan memeriksa Cache HTTP dan menemukan respons sebelumnya. Sayangnya, browser tidak dapat menggunakan respons sebelumnya karena respons tersebut telah berakhir. Pada tahap ini, browser dapat mengirimkan permintaan baru dan mengambil respons lengkap yang baru. Namun, hal tersebut tidak efisien karena jika resource tidak berubah, tidak ada alasan untuk mendownload informasi yang sama yang sudah ada di cache. Untuk mengatasi masalah itulah, token validasi, sebagaimana ditentukan dalam header ETag, dirancang untuk mengatasi masalah tersebut. Server membuat dan menampilkan token arbitrer, yang biasanya berupa hash atau sidik jari lain dari konten file. Browser tidak perlu mengetahui cara sidik jari dihasilkan; browser hanya perlu mengirimkannya ke server pada permintaan berikutnya. Jika sidik jarinya masih sama, artinya resource belum berubah dan browser dapat melewati download.

Dengan menetapkan ETag atau Last-Modified, Anda akan membuat permintaan validasi ulang menjadi jauh lebih efisien. Keduanya pada akhirnya memicu header permintaan If-Modified-Since atau If-None-Match yang disebutkan dalam Header permintaan.

Ketika server web yang dikonfigurasi dengan benar melihat header permintaan masuk tersebut, server web dapat mengonfirmasi apakah versi resource yang sudah dimiliki browser di Cache HTTP cocok dengan versi terbaru di server web. Jika ada kecocokan, server dapat merespons dengan respons HTTP 304 Not Modified, yang setara dengan "Hei, tetap gunakan yang sudah Anda miliki!" Data yang dapat ditransfer saat mengirim jenis respons ini sangat sedikit, jadi biasanya jauh lebih cepat daripada harus benar-benar mengirim kembali salinan resource aktual yang diminta.

Diagram klien yang meminta resource dan server merespons dengan header 304.
Browser meminta /file dari server dan menyertakan header If-None-Match untuk memerintahkan server hanya menampilkan file lengkap jika ETag file di server tidak cocok dengan nilai If-None-Match browser. Dalam kasus ini, kedua nilai tersebut cocok, sehingga server menampilkan respons 304 Not Modified dengan petunjuk tentang berapa lama file harus disimpan dalam cache (Cache-Control: max-age=120).

Ringkasan

Cache HTTP adalah cara efektif untuk meningkatkan performa pemuatan karena mengurangi permintaan jaringan yang tidak perlu. Ini didukung di semua browser dan tidak membutuhkan terlalu banyak pekerjaan untuk menyiapkannya.

Konfigurasi Cache-Control berikut adalah awal yang baik:

  • Cache-Control: no-cache untuk resource yang harus divalidasi ulang dengan server sebelum setiap penggunaan.
  • Cache-Control: no-store untuk resource yang tidak boleh di-cache.
  • Cache-Control: max-age=31536000 untuk resource berversi.

Dan header ETag atau Last-Modified dapat membantu Anda memvalidasi ulang resource cache yang telah habis masa berlakunya secara lebih efisien.

Pelajari lebih lanjut

Jika Anda ingin mengetahui lebih dari dasar-dasar penggunaan header Cache-Control, lihat panduan Praktik terbaik cache & gotcha usia maksimal dari Jake Archibald.

Lihat Menyukai cache Anda untuk mendapatkan panduan tentang cara mengoptimalkan penggunaan cache bagi pengunjung yang kembali.

Lampiran: Tips lainnya

Jika Anda memiliki lebih banyak waktu, berikut adalah cara selanjutnya untuk mengoptimalkan penggunaan Cache HTTP:

  • Gunakan URL yang konsisten. Jika Anda menayangkan konten yang sama di URL yang berbeda, konten tersebut akan diambil dan disimpan beberapa kali.
  • Minimalkan churn. Jika bagian resource (seperti file CSS) sering diperbarui, sedangkan sisa file lainnya tidak (seperti kode library), pertimbangkan untuk membagi kode yang sering diperbarui ke dalam file terpisah dan menggunakan strategi caching berdurasi singkat untuk kode yang sering diperbarui dan strategi durasi cache yang panjang untuk kode yang tidak sering berubah.
  • Lihat perintah stale-while-revalidate baru jika tingkat penghentian tertentu dapat diterima dalam kebijakan Cache-Control Anda.

Lampiran: Diagram alir Cache-Control

Diagram alir

Lampiran: Cache-Control contoh

Nilai Cache-Control Penjelasan
max-age=86400 Respons dapat disimpan dalam cache oleh browser dan cache perantara hingga 1 hari (60 detik x 60 menit x 24 jam).
private, max-age=600 Respons dapat di-cache oleh browser (tetapi tidak dalam cache perantara) hingga 10 menit (60 detik x 10 menit).
public, max-age=31536000 Respons dapat disimpan oleh cache apa pun selama 1 tahun.
no-store Respons tidak diizinkan untuk disimpan dalam cache dan harus diambil secara penuh pada setiap permintaan.