Mencegah permintaan jaringan yang tidak perlu dengan Cache HTTP

Mengambil resource melalui jaringan lambat dan mahal:

  • Respons besar memerlukan banyak perjalanan bolak-balik antara browser dan server.
  • Halaman Anda tidak akan dimuat hingga semua resource penting-nya didownload sepenuhnya.
  • Jika seseorang mengakses situs Anda dengan paket data seluler yang terbatas, setiap permintaan jaringan yang tidak perlu akan membuang-buang uangnya.

Bagaimana cara menghindari permintaan jaringan yang tidak perlu? Cache HTTP browser adalah pertahanan pertama Anda. Ini bukan pendekatan yang paling efektif atau fleksibel, dan Anda memiliki kontrol terbatas atas masa aktif respons yang di-cache, tetapi ini efektif, didukung di semua browser, dan tidak memerlukan banyak pekerjaan.

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

Kompatibilitas browser

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

Cache-Control

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

ETag

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Last-Modified

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Cara kerja Cache HTTP

Semua permintaan HTTP yang dibuat browser pertama-tama dirutekan ke cache browser untuk memeriksa apakah ada respons yang di-cache yang valid dan dapat digunakan untuk memenuhi permintaan. Jika ada kecocokan, respons akan dibaca dari cache, yang menghilangkan latensi jaringan dan biaya data yang dikeluarkan transfer.

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

Lihat artikel Pembuatan Cache HTTP MDN untuk ringkasan konseptual yang lebih mendalam.

Header permintaan: tetap menggunakan default (biasanya)

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

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

Header respons: mengonfigurasi server web

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

  • Cache-Control. Server dapat menampilkan perintah Cache-Control untuk menentukan cara, dan berapa lama, browser dan cache perantara lainnya harus menyimpan respons individual dalam cache.
  • ETag. Saat menemukan respons yang di-cache yang telah habis masa berlakunya, browser dapat mengirim token kecil (biasanya hash konten file) ke server untuk memeriksa apakah file telah berubah. Jika server menampilkan token yang sama, file tersebut sama, dan tidak perlu mendownloadnya lagi.
  • Last-Modified. Header ini memiliki tujuan yang sama dengan ETag, tetapi menggunakan strategi berbasis waktu untuk menentukan apakah resource telah berubah, bukan strategi berbasis konten ETag.

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

Agar Anda tidak perlu melakukan penelusuran, berikut adalah petunjuk untuk mengonfigurasi beberapa server web populer:

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

Nilai header respons mana yang harus Anda gunakan?

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

Cache yang tahan lama untuk URL yang memiliki versi

Misalnya, server Anda menginstruksikan browser untuk meng-cache file CSS selama 1 tahun (Cache-Control: max-age=31536000), tetapi desainer Anda baru saja melakukan update darurat yang perlu segera di-deploy. Bagaimana cara memberi tahu browser untuk memperbarui salinan file yang di-cache dan "tidak berlaku lagi"? Anda tidak dapat melakukannya, setidaknya tidak tanpa mengubah URL resource.

Setelah browser menyimpan respons dalam cache, versi yang di-cache akan digunakan hingga tidak lagi baru, seperti yang ditentukan oleh max-age atau expires, atau hingga dihapus dari cache karena alasan lain—misalnya, pengguna menghapus cache browser mereka. Akibatnya, pengguna yang berbeda mungkin menggunakan versi file yang berbeda saat halaman dibuat: pengguna yang baru saja mengambil resource menggunakan versi baru, sedangkan pengguna yang meng-cache salinan sebelumnya (tetapi masih valid) menggunakan versi respons yang lebih lama.

Bagaimana cara mendapatkan yang terbaik dari kedua hal tersebut: cache sisi klien dan update cepat? Anda mengubah URL resource dan memaksa pengguna untuk 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 kontennya tidak pernah dimaksudkan untuk berubah, tambahkan Cache-Control: max-age=31536000 ke respons Anda.

Menetapkan 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 di Cache HTTP, tanpa harus membuat permintaan jaringan ke server web Anda sama sekali. Bagus—Anda langsung mendapatkan keandalan dan kecepatan yang berasal dari 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. Selain itu, setiap aplikasi web memerlukan file HTML—file tersebut (hampir) tidak akan pernah menyertakan informasi pembuatan versi, karena tidak ada yang akan repot 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 yang mengharuskan Anda mengakui kekalahan. Cache HTTP saja tidak cukup kuat untuk menghindari jaringan sepenuhnya. (Jangan khawatir—Anda akan segera mempelajari pekerja layanan, yang akan memberikan dukungan yang diperlukan untuk memenangkan pertempuran.) Namun, ada beberapa langkah yang dapat Anda lakukan untuk memastikan permintaan jaringan secepat dan seefisien mungkin.

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

  • no-cache. Hal ini akan memberi tahu browser bahwa browser harus memvalidasi ulang dengan server setiap kali sebelum menggunakan versi URL yang di-cache.
  • no-store. Tindakan ini akan memerintahkan 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.
  • public. Respons dapat disimpan oleh cache apa pun.

Lihat Lampiran: Diagram alir Cache-Control untuk memvisualisasikan proses menentukan nilai Cache-Control yang akan digunakan. Cache-Control juga dapat menerima daftar perintah yang dipisahkan koma. Lihat Lampiran: Contoh Cache-Control.

Menyetel ETag atau Last-Modified juga dapat membantu. Seperti yang disebutkan dalam Header respons, ETag dan Last-Modified memiliki tujuan yang sama: menentukan apakah browser perlu mendownload ulang file yang di-cache yang telah habis masa berlakunya. Sebaiknya gunakan ETag karena lebih akurat.

Asumsikan bahwa 120 detik telah berlalu sejak pengambilan awal dan browser telah memulai permintaan baru untuk resource yang sama. Pertama, browser memeriksa Cache HTTP dan menemukan respons sebelumnya. Sayangnya, browser tidak dapat menggunakan respons sebelumnya karena masa berlaku respons tersebut telah berakhir. Pada tahap ini, browser dapat mengirim permintaan baru dan mengambil respons lengkap baru. Namun, hal ini tidak efisien karena jika resource belum berubah, tidak ada alasan untuk mendownload informasi yang sama yang sudah ada di cache.

Itulah masalah yang dirancang untuk dipecahkan oleh token validasi, seperti yang ditentukan dalam header ETag. Server membuat dan menampilkan token arbitrer, yang biasanya berupa hash atau beberapa sidik jari lain dari konten file. Browser tidak perlu mengetahui cara pembuatan sidik jari; browser hanya perlu mengirimkannya ke server pada permintaan berikutnya. Jika sidik jari masih sama, berarti resource belum berubah dan browser dapat melewati download.

Menetapkan ETag atau Last-Modified, membuat permintaan validasi ulang jauh lebih efisien dengan membiarkannya memicu header permintaan If-Modified-Since atau If-None-Match yang disebutkan dalam Header permintaan.

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

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

Ringkasan

Cache HTTP adalah cara efektif untuk meningkatkan performa pemuatan karena mengurangi permintaan jaringan yang tidak perlu. Fitur ini didukung di semua browser dan tidak memerlukan banyak pekerjaan untuk disiapkan.

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.

Selain itu, header ETag atau Last-Modified dapat membantu Anda memvalidasi ulang resource cache yang sudah tidak berlaku secara lebih efisien.

Pelajari lebih lanjut

Jika Anda ingin mempelajari lebih lanjut dasar-dasar penggunaan header Cache-Control, lihat panduan Praktik terbaik penyimpanan dalam cache dan masalah max-age dari Jake Archibald.

Lihat Mencintai cache untuk mendapatkan panduan tentang cara mengoptimalkan penggunaan cache untuk pengunjung yang kembali.

Lampiran: Tips lainnya

Jika Anda memiliki lebih banyak waktu, berikut adalah cara lebih lanjut 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.
  • Meminimalkan churn. Jika sebagian resource (seperti file CSS) sering diperbarui, sedangkan bagian file lainnya tidak (seperti kode library), pertimbangkan untuk memisahkan kode yang sering diperbarui ke dalam file terpisah dan menggunakan strategi penyimpanan dalam cache berdurasi singkat untuk kode yang sering diperbarui dan strategi penyimpanan dalam cache berdurasi lama untuk kode yang tidak sering berubah.
  • Lihat perintah stale-while-revalidate baru jika tingkat keusangan tertentu dapat diterima dalam kebijakan Cache-Control Anda.

Lampiran: diagram alir Cache-Control

Diagram alir
Proses pengambilan keputusan untuk menetapkan header Cache-Control.

Lampiran: Contoh Cache-Control

Nilai Cache-Control Penjelasan
max-age=86400 Respons dapat di-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 untuk 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 di-cache dan harus diambil sepenuhnya pada setiap permintaan.