Mencegah permintaan jaringan yang tidak perlu dengan Cache HTTP

Mengambil resource melalui jaringan berjalan lambat dan mahal:

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

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

Panduan ini menunjukkan dasar-dasar penerapan penyimpanan 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

Dukungan Browser

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

Sumber

ETag

Dukungan Browser

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

Sumber

Last-Modified

Dukungan Browser

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

Sumber

Cara kerja Cache HTTP

Semua permintaan HTTP yang dibuat browser akan dirutekan ke cache browser terlebih dulu untuk memeriksa apakah ada respons valid yang di-cache yang bisa digunakan untuk memenuhi permintaan. 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. Idealnya, 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 HTTP Caching 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 setelannya 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 otomatis menangani penyimpanan cache HTTP untuk Anda, tanpa upaya tambahan.

Header respons: mengonfigurasi server web

Bagian dari pengaturan {i>caching<i} HTTP yang paling penting adalah {i>header<i} yang ditambahkan server web Anda ke setiap respons keluar. Semua header berikut memengaruhi perilaku caching yang efektif:

  • Cache-Control Server dapat menampilkan perintah Cache-Control untuk menentukan bagaimana, serta berapa lama, browser dan cache perantara lainnya harus meng-cache respons individual.
  • ETag Saat menemukan respons yang di-cache yang sudah tidak berlaku, browser dapat mengirimkan 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 Anda tidak perlu mendownload ulang token tersebut.
  • Last-Modified Header ini memiliki fungsi 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 menyetel header tersebut secara default, sementara yang lain tidak menggunakan header sepenuhnya kecuali 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 waktu penelusuran, berikut adalah petunjuk tentang cara mengonfigurasi beberapa server web yang populer:

Tidak menyertakan header respons Cache-Control tidak akan menonaktifkan penyimpanan cache HTTP. Sebaliknya, browser secara efektif menebak jenis perilaku penyimpanan dalam cache yang paling masuk akal untuk jenis konten tertentu. Kemungkinan Anda menginginkan lebih banyak kontrol daripada yang ditawarkan, jadi luangkan waktu untuk mengonfigurasi {i>header<i} 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

Misalkan server Anda memerintahkan 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 Anda deploy. Bagaimana cara memberi tahu browser untuk memperbarui "tidak berlaku" salinan file yang di-cache? Anda tidak bisa, setidaknya tanpa mengubah URL sumber daya.

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

Bagaimana Anda mendapatkan yang terbaik dari kedua hal tersebut: penyimpanan cache sisi klien dan pembaruan 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 ingin diubah, tambahkan Cache-Control: max-age=31536000 ke respons Anda.

Menyetel nilai ini akan memberi tahu browser bahwa ketika 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. Itu bagus—Anda bisa langsung mendapatkan keandalan dan kecepatan yang didapatkan 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 tersebut (hampir) tidak akan pernah menyertakan informasi pembuatan versi, karena tidak ada yang akan mau 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 harus mengakui kekalahan. Cache HTTP saja tidak cukup kuat untuk menghindari jaringan sepenuhnya. (Jangan khawatir—Anda akan segera mempelajari tentang pekerja layanan, yang akan memberikan dukungan yang kami butuhkan untuk kembali berjuang demi kebaikan Anda.) Tetapi ada beberapa langkah yang dapat Anda ambil untuk memastikan bahwa permintaan jaringan secepat dan seefisien mungkin.

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

  • no-cache. Hal ini menginstruksikan browser bahwa setiap kali harus memvalidasi ulang dengan server sebelum menggunakan versi URL yang di-cache.
  • no-store. Hal ini menginstruksikan browser dan cache perantara lainnya (seperti CDN) agar tidak pernah menyimpan versi file apa pun.
  • private. Browser dapat meng-cache file tetapi cache perantara tidak.
  • public. Respons dapat disimpan oleh cache apa 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: Cache-Control contoh.

Menetapkan ETag atau Last-Modified juga dapat membantu. Seperti yang disebutkan di Header respons, ETag dan Last-Modified memiliki tujuan yang sama: menentukan apakah browser perlu mendownload ulang file yang di-cache yang masa berlakunya telah habis. 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 akan memeriksa Cache HTTP dan menemukan respons sebelumnya. Sayangnya, browser tidak dapat menggunakan respons sebelumnya karena respons tersebut kini sudah tidak berlaku. Pada tahap ini, browser dapat mengirimkan permintaan baru dan mengambil respons lengkap yang baru. Namun, hal itu tidak efisien karena jika resource tidak berubah, tidak ada alasan untuk mendownload informasi yang sama dengan yang sudah ada di cache.

Untuk mengatasi masalah tersebut, token validasi, sebagaimana ditentukan dalam header ETag, Server menghasilkan dan menampilkan token arbitrer, yang biasanya berupa hash atau beberapa sidik jari lain dari konten file. Browser tidak perlu mengetahui bagaimana sidik jari dihasilkan; klien hanya perlu mengirimkannya ke server pada permintaan berikutnya. Jika sidik jari masih sama, berarti resource belum berubah dan browser dapat melewati download.

Menyetel ETag atau Last-Modified akan membuat permintaan validasi ulang jauh lebih efisien dengan mengizinkannya 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 telah 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, tetap gunakan yang sudah Anda dapatkan!" Ada sangat sedikit data yang perlu ditransfer saat mengirim jenis respons ini, jadi biasanya jauh lebih cepat daripada benar-benar mengirim kembali salinan sumber daya aktual yang diminta.

Visualisasi klien yang meminta resource dan server merespons dengan header 304.
Browser meminta /file dari server dan menyertakan header If-None-Match untuk memerintahkan 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 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. Dukungan di semua browser dan tidak membutuhkan terlalu banyak upaya untuk menyiapkannya.

Konfigurasi Cache-Control berikut merupakan 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 mengetahui lebih dari sekadar dasar-dasar penggunaan header Cache-Control, baca panduan Praktik terbaik penyimpanan cache dan cara mendapatkannya dari Jake Archibald.

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

Lampiran: Tips lainnya

Jika Anda memiliki lebih banyak waktu, berikut cara lain 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 dari resource (seperti file CSS) sering diperbarui, sedangkan bagian file lainnya tidak (seperti kode library), pertimbangkan untuk membagi kode yang sering diupdate menjadi file terpisah dan menggunakan strategi caching berdurasi singkat untuk kode yang sering diupdate dan strategi caching durasi yang panjang untuk kode yang tidak sering berubah.
  • Lihat perintah stale-while-revalidate baru jika beberapa tingkat penghentian dapat diterima dalam kebijakan Cache-Control Anda.

Lampiran: Cache-Control diagram alir

Diagram alir
Proses keputusan untuk menyetel header Cache-Control.

Lampiran: Cache-Control contoh

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.