Sukai cache Anda ❤️

Pengguna yang memuat situs Anda untuk kedua kalinya akan menggunakan cache HTTP mereka, jadi pastikan cache tersebut berfungsi dengan baik.

Postingan ini adalah pendamping untuk video Mencintai cache, bagian dari Konten Ekstensi di Chrome Dev Summit 2020. Pastikan untuk menonton videonya:

Saat pengguna memuat situs Anda untuk kedua kalinya, browser mereka akan menggunakan resource di dalam cache HTTP untuk membantu mempercepat pemuatan tersebut. Namun, standar untuk menyimpan dalam cache di web sudah ada sejak tahun 1999, dan standar tersebut ditentukan secara cukup luas—menentukan apakah file, seperti CSS atau gambar, dapat diambil lagi dari jaringan atau dimuat dari cache Anda adalah hal yang tidak pasti.

Dalam postingan ini, saya akan menjelaskan default yang logis dan modern untuk caching—yang sebenarnya tidak melakukan caching sama sekali. Namun, itu hanya setelan default, dan tentu saja lebih mendetail daripada sekadar "menonaktifkannya". Baca selengkapnya.

Sasaran

Saat situs dimuat untuk ke-2 kalinya, Anda memiliki dua sasaran:

  1. Pastikan pengguna Anda mendapatkan versi terbaru yang tersedia—jika Anda telah mengubah sesuatu, perubahan tersebut akan segera diterapkan
  2. Lakukan #1 sambil mengambil sesedikit mungkin dari jaringan

Secara luas, Anda hanya ingin mengirim perubahan terkecil kepada klien saat mereka memuat situs Anda lagi. Selain itu, menyusun situs untuk memastikan distribusi perubahan yang paling efisien tidaklah mudah (selengkapnya di bawah, dan dalam video).

Meskipun demikian, Anda juga memiliki tombol lain saat mempertimbangkan penyimpanan dalam cache—mungkin Anda telah memutuskan untuk mengizinkan cache HTTP browser pengguna menyimpan situs Anda selama waktu yang lama sehingga tidak ada permintaan jaringan yang diperlukan untuk menayangkannya sama sekali. Atau, Anda telah membuat pekerja layanan yang akan menayangkan situs sepenuhnya secara offline sebelum memeriksa apakah situs tersebut sudah yang terbaru. Ini adalah opsi ekstrem, yang valid—dan digunakan untuk banyak pengalaman web yang mirip dengan aplikasi offline-first—tetapi web tidak harus merupakan ekstrem hanya cache, atau bahkan ekstrem hanya jaringan.

Latar belakang

Sebagai developer web, kita semua terbiasa dengan gagasan memiliki "cache yang sudah tidak berlaku". Namun, hampir secara naluriah, kita tahu alat-alat yang tersedia untuk mengatasi hal ini: lakukan "refresh keras", atau buka jendela samaran, atau gunakan beberapa kombinasi alat developer di browser Anda untuk menghapus data situs.

Pengguna biasa di internet tidak memiliki kemewahan yang sama. Jadi, meskipun kita memiliki beberapa sasaran inti untuk memastikan pengguna menikmati pemuatan ke-2, penting juga untuk memastikan mereka tidak mengalami masalah atau macet. (Lihat videonya jika ingin mendengar saya menceritakan bagaimana kami nyaris membuat situs web.dev/live macet.)

Sebagai sedikit latar belakang, alasan yang sangat umum untuk "cache usang" sebenarnya adalah setelan default untuk penyimpanan dalam cache pada tahun 1999. Fungsi ini bergantung pada header Last-Modified:

Diagram yang menunjukkan berapa lama berbagai aset di-cache oleh browser pengguna
Aset yang dibuat pada waktu yang berbeda (berwarna abu-abu) akan di-cache untuk waktu yang berbeda, sehingga pemuatan ke-2 dapat mendapatkan kombinasi aset yang di-cache dan baru

Setiap file yang Anda muat disimpan selama 10% tambahan dari masa aktifnya saat ini, seperti yang dilihat browser Anda. Misalnya, jika index.html dibuat sebulan yang lalu, index.html akan di-cache oleh browser Anda selama sekitar tiga hari lagi.

Ini adalah ide yang baik pada masa lalu, tetapi mengingat sifat situs saat ini yang terintegrasi rapat, perilaku default ini berarti pengguna dapat berada dalam status saat pengguna memiliki file yang dirancang untuk rilis situs yang berbeda (misalnya, JS dari rilis hari Selasa, dan CSS dari rilis hari Jumat), semua karena file tersebut tidak diperbarui pada waktu yang sama.

Jalur yang terang

Default modern untuk penyimpanan dalam cache adalah tidak melakukan penyimpanan dalam cache sama sekali, dan menggunakan CDN untuk mendekatkan konten Anda kepada pengguna. Setiap kali pengguna memuat situs Anda, mereka akan membuka jaringan untuk melihat apakah situs tersebut sudah yang terbaru. Permintaan ini akan memiliki latensi rendah, karena akan disediakan oleh CDN yang berada di dekat setiap pengguna akhir secara geografis.

Anda dapat mengonfigurasi host web untuk merespons permintaan web dengan header ini:

Cache-Control: max-age=0,must-revalidate,public

Ini pada dasarnya menyatakan bahwa file tidak valid untuk waktu yang lama, dan Anda harus memvalidasinya dari jaringan sebelum dapat menggunakannya lagi (jika tidak, file tersebut hanya "disarankan").

Proses validasi ini relatif murah dalam hal byte yang ditransfer—jika file gambar besar belum berubah, browser Anda akan menerima respons 304 kecil—tetapi proses ini memerlukan latensi karena pengguna masih harus terhubung ke jaringan untuk mengetahuinya. Dan ini adalah kelemahan utama dari pendekatan ini. Solusi ini dapat berfungsi dengan sangat baik untuk orang-orang yang menggunakan koneksi cepat di negara maju, dan jika CDN pilihan Anda memiliki cakupan yang bagus, tetapi tidak untuk orang-orang yang mungkin menggunakan koneksi seluler yang lebih lambat atau menggunakan infrastruktur yang buruk.

Namun, ini adalah pendekatan modern yang merupakan default di CDN populer, Netlify, tetapi dapat dikonfigurasi di hampir semua CDN. Untuk Firebase Hosting, Anda dapat menyertakan header ini di bagian hosting file firebase.json:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Jadi, meskipun saya masih menyarankannya sebagai setelan default yang wajar, ini hanyalah setelan default. Baca terus untuk mengetahui cara memasuki dan mengupgrade versi default.

URL dengan sidik jari

Dengan menyertakan hash konten file dalam nama aset, gambar, dan sebagainya yang ditayangkan di situs Anda, Anda dapat memastikan bahwa file ini akan selalu memiliki konten unik. Misalnya, file akan diberi nama sitecode.af12de.js. Saat server merespons permintaan untuk file ini, Anda dapat dengan aman memerintahkan browser pengguna akhir untuk meng-cache file tersebut dalam waktu yang lama dengan mengonfigurasinya menggunakan header ini:

Cache-Control: max-age=31536000,immutable

Nilai ini adalah satu tahun, dalam detik. Dan menurut spesifikasi, hal ini secara efektif sama dengan "selamanya".

Yang penting, jangan buat hash ini secara manual—ini terlalu banyak pekerjaan manual. Anda dapat menggunakan alat seperti Webpack, Rollup, dan sebagainya untuk membantu menangani hal ini. Pastikan untuk membacanya lebih lanjut di Laporan Alat.

Perlu diingat bahwa bukan hanya JavaScript yang dapat memanfaatkan URL dengan sidik jari; aset seperti ikon, CSS, dan file data lain yang tidak dapat diubah juga dapat diberi nama seperti ini. (Dan pastikan untuk menonton video di atas untuk mempelajari lebih lanjut pemisahan kode, yang memungkinkan Anda mengirimkan lebih sedikit kode setiap kali situs Anda berubah.)

Terlepas dari cara situs Anda menangani penyimpanan dalam cache, jenis file dengan sidik jari ini sangat berharga untuk situs apa pun yang mungkin Anda buat. Sebagian besar situs hanya tidak berubah pada setiap rilis.

Tentu saja, kita tidak dapat mengganti nama halaman 'ramah' yang ditampilkan kepada pengguna dengan cara ini: mengganti nama file index.html menjadi index.abcd12.html—hal ini tidak dapat dilakukan, Anda tidak dapat meminta pengguna untuk membuka URL baru setiap kali mereka memuat situs Anda. URL yang ramah ini tidak dapat diganti namanya dan di-cache dengan cara ini, yang membawa saya ke titik tengah yang mungkin terjadi.

Jalan tengah

Tentu saja ada jalan tengah dalam hal penyimpanan dalam cache. Saya telah menampilkan dua opsi ekstrem; cache tidak pernah, atau cache selamanya. Dan akan ada sejumlah file yang mungkin ingin Anda cache untuk sementara waktu, seperti URL "ramah" yang saya sebutkan di atas.

Jika Anda ingin meng-cache URL "ramah" ini dan HTML-nya, sebaiknya pertimbangkan dependensi yang disertakan, cara mereka dapat di-cache, dan cara meng-cache URL mereka untuk sementara waktu dapat memengaruhi Anda. Mari kita lihat halaman HTML yang menyertakan gambar seperti ini:

<img src="/images/foo.jpeg" loading="lazy" />

Jika Anda memperbarui atau mengubah situs dengan menghapus atau mengubah gambar yang dimuat secara lambat ini, pengguna yang melihat versi HTML Anda yang di-cache mungkin mendapatkan gambar yang salah atau tidak ada karena mereka masih meng-cache /images/foo.jpeg asli saat mereka mengunjungi kembali situs Anda.

Jika Anda berhati-hati, hal ini mungkin tidak akan memengaruhi Anda. Namun, secara umum, penting untuk mengingat bahwa situs Anda—saat di-cache oleh pengguna akhir—tidak lagi hanya ada di server Anda. Sebaliknya, data tersebut mungkin ada dalam bagian di dalam cache browser pengguna akhir Anda.

Secara umum, sebagian besar panduan tentang penyimpanan dalam cache akan membahas jenis setelan ini—apakah Anda ingin menyimpan dalam cache selama satu jam, beberapa jam, dan sebagainya. Untuk menyiapkan cache semacam ini, gunakan header seperti ini (yang di-cache selama 3.600 detik, atau satu jam):

Cache-Control: max-age=3600,immutable,public

Satu hal terakhir. Jika Anda membuat konten yang aktual dan biasanya hanya diakses oleh pengguna sekali—seperti artikel berita—pendapat saya adalah konten tersebut tidak boleh di-cache, dan Anda harus menggunakan setelan default yang wajar di atas. Saya rasa kita sering mengabaikan nilai penyimpanan dalam cache dibandingkan keinginan pengguna untuk selalu melihat konten terbaru dan terbaik, seperti update penting pada artikel berita atau peristiwa terkini.

Opsi non-HTML

Selain HTML, beberapa opsi lain untuk file yang berada di tengah-tengah meliputi:

  • Secara umum, cari aset yang tidak memengaruhi aset lain

    • Misalnya: hindari CSS, karena menyebabkan perubahan pada cara HTML Anda dirender
  • Gambar besar yang digunakan sebagai bagian dari artikel yang relevan

    • Pengguna Anda mungkin tidak akan mengunjungi satu artikel lebih dari beberapa kali, jadi jangan menyimpan foto atau gambar hero dalam cache selamanya dan membuang penyimpanan
  • Aset yang mewakili sesuatu yang memiliki masa aktif

    • Data JSON tentang cuaca mungkin hanya dipublikasikan setiap jam, sehingga Anda dapat menyimpan hasil sebelumnya ke dalam cache selama satu jam—hasil tersebut tidak akan berubah di jendela Anda
    • Build project open source mungkin dibatasi kapasitasnya, jadi cache gambar status build hingga statusnya mungkin berubah

Ringkasan

Saat pengguna memuat situs Anda untuk kedua kalinya, Anda telah mendapatkan kepercayaan mereka—mereka ingin kembali dan mendapatkan lebih banyak hal yang Anda tawarkan. Pada tahap ini, Anda tidak selalu hanya ingin mengurangi waktu muat, dan Anda memiliki banyak opsi yang tersedia untuk memastikan bahwa browser melakukan tugas yang diperlukan untuk memberikan pengalaman yang cepat dan terbaru.

Penyimpanan dalam cache bukanlah konsep baru di web, tetapi mungkin memerlukan setelan default yang wajar. Pertimbangkan untuk menggunakannya dan memilih untuk menggunakan strategi penyimpanan dalam cache yang lebih baik saat Anda membutuhkannya. Terima kasih telah membaca.

Lihat juga

Untuk panduan umum tentang cache HTTP, lihat Mencegah permintaan jaringan yang tidak perlu dengan Cache HTTP.