Mencegah permintaan jaringan yang tidak perlu dengan Cache HTTP

Mengambil resource melalui jaringan lambat dan mahal:

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

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

Panduan ini menunjukkan dasar-dasar penerapan caching HTTP yang efektif.

Kompatibilitas browser

Sebenarnya tidak ada satu API pun yang disebut Cache HTTP. HTML5 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 akan dirutekan terlebih dahulu ke cache browser untuk memeriksa apakah ada respons yang di-cache yang valid yang dapat digunakan untuk memenuhi permintaan. Jika ada kecocokan, respons akan dibaca dari cache, sehingga menghilangkan latensi jaringan dan biaya data yang timbul akibat 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 Caching HTTP MDN untuk ringkasan konseptual yang lebih mendalam.

Header permintaan: Gunakan setelan default (biasanya)

Ada sejumlah header penting yang harus disertakan dalam permintaan keluar aplikasi web Anda, tetapi browser hampir selalu menangani penyetelannya atas nama 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"> dalam HTML, dan browser akan otomatis menangani caching HTTP untuk Anda, tanpa upaya ekstra.

Header respons: Mengonfigurasi server web Anda

Bagian penyiapan caching HTTP yang paling penting adalah header yang ditambahkan server web Anda ke setiap respons keluar. Header berikut semuanya memengaruhi perilaku caching yang efektif:

  • Cache-Control. Server dapat menampilkan perintah Cache-Control untuk menentukan cara dan durasi browser serta cache perantara lainnya harus meng-cache setiap respons.
  • ETag. Saat browser menemukan respons yang di-cache yang sudah tidak berlaku, browser dapat mengirimkan token kecil (biasanya hash dari konten file) ke server untuk memeriksa apakah file telah berubah. Jika server menampilkan token yang sama, berarti file tersebut sama, dan tidak perlu didownload ulang.
  • 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 seperti ETag.

Beberapa server web memiliki dukungan bawaan untuk menetapkan header tersebut secara default, sementara server web 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. Anda harus membaca dokumentasi server untuk mendapatkan detail yang paling akurat.

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

Menghilangkan header respons Cache-Control tidak akan menonaktifkan caching HTTP. Sebagai gantinya, browser secara efektif menebak jenis perilaku caching yang paling sesuai untuk jenis konten tertentu. Kemungkinan Anda menginginkan kontrol yang lebih besar 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.

Cache yang tahan lama untuk URL berversi

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

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

Setelah browser meng-cache respons, 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 browsernya. Akibatnya, pengguna yang berbeda mungkin akan menggunakan versi file yang berbeda saat halaman dibuat: pengguna yang baru saja mengambil resource akan menggunakan versi baru, sedangkan pengguna yang meng-cache salinan sebelumnya (tetapi masih valid) akan menggunakan versi respons yang lebih lama.

Bagaimana cara mendapatkan yang terbaik dari kedua hal tersebut: caching sisi klien dan update cepat? Anda 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 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 diperoleh 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. Dan setiap aplikasi web memerlukan file HTML—file tersebut (hampir!) tidak akan pernah menyertakan informasi pembuatan versi, karena tidak ada yang akan repot-repot menggunakan aplikasi web Anda jika mereka harus mengingat bahwa URL yang harus dikunjungi adalah https://example.com/index.34def12.html. Jadi, apa yang dapat Anda lakukan untuk URL tersebut?

Ini adalah salah satu skenario saat Anda harus mengakui kekalahan. Caching HTTP saja tidak cukup kuat untuk menghindari jaringan sepenuhnya. (Jangan khawatir—Anda akan segera mempelajari service worker, yang akan memberikan dukungan yang kita perlukan untuk memenangkan pertempuran ini.) Namun, ada beberapa langkah yang dapat Anda lakukan untuk memastikan bahwa 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 menginstruksikan browser bahwa browser harus melakukan validasi ulang dengan server setiap kali sebelum menggunakan versi URL yang di-cache.
  • no-store. Hal 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 mana pun.

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

Menetapkan 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.

Contoh ETag

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 respons tersebut kini telah habis masa berlakunya. Pada tahap ini, browser dapat mengirimkan permintaan baru dan mengambil respons lengkap yang baru. Namun, hal ini tidak efisien karena jika resource tidak berubah, tidak ada alasan untuk mendownload informasi yang sama yang sudah ada di cache.

Itulah masalah yang dirancang untuk diselesaikan oleh token validasi, seperti yang ditentukan dalam header ETag. Server membuat dan menampilkan token arbitrer, yang biasanya berupa hash atau sidik jari lain dari konten file. Browser tidak perlu mengetahui cara sidik jari dibuat; 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 akan membuat permintaan validasi ulang jauh lebih efisien dengan memungkinkannya memicu header permintaan If-Modified-Since atau If-None-Match yang disebutkan di Header permintaan.

Saat 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-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!" Data yang perlu ditransfer saat mengirim respons jenis ini sangat sedikit, sehingga biasanya jauh lebih cepat daripada harus mengirim kembali salinan resource yang 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, kedua 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

HTTP Cache adalah cara yang efektif untuk meningkatkan performa pemuatan karena mengurangi permintaan jaringan yang tidak perlu. Storage Access API didukung di semua browser dan tidak memerlukan banyak upaya 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.

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 penggunaan header Cache-Control, lihat panduan Praktik terbaik caching dan masalah max-age dari Jake Archibald.

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

Lampiran: Tips lainnya

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

  • Gunakan URL yang konsisten. Jika Anda menyajikan konten yang sama di URL yang berbeda, konten tersebut akan diambil dan disimpan beberapa kali.
  • Meminimalkan churn. Jika sebagian resource (seperti file CSS) sering diupdate, sedangkan bagian file lainnya tidak (seperti kode library), pertimbangkan untuk memisahkan kode yang sering diupdate ke dalam file terpisah dan menggunakan strategi caching berdurasi singkat untuk kode yang sering diupdate dan strategi caching berdurasi panjang untuk kode yang jarang berubah.
  • Lihat perintah stale-while-revalidate baru jika beberapa tingkat keusangan dapat diterima dalam kebijakan Cache-Control Anda.

Lampiran: Diagram alir Cache-Control

Diagram Alir
Proses keputusan untuk menetapkan header Cache-Control Anda.

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 bukan 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 secara penuh pada setiap permintaan.