Sukai cache Anda ❤️

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

Postingan ini adalah pengiring untuk video Love your cache, yang merupakan bagian dari Konten yang Diperluas di Chrome Dev Summit 2020. Pastikan untuk menonton video:

Saat pengguna memuat situs Anda untuk kedua kalinya, browser mereka akan menggunakan resource di dalam cache HTTP untuk membantu mempercepat pemuatan. Namun, standar untuk caching di web dimulai pada tahun 1999, dan sudah sangat luas. Menentukan apakah file, seperti CSS atau gambar, dapat diambil kembali dari jaringan, bukan yang dimuat dari cache, merupakan hal yang tidak tepat.

Dalam postingan ini, saya akan membahas default yang logis dan modern untuk caching, yang sebenarnya tidak melakukan caching sama sekali. Tapi itu hanya default, dan tentu saja lebih bernuansa daripada sekedar "mematikan". Baca selengkapnya.

Tujuan

Saat situs dimuat untuk kedua kalinya, Anda memiliki dua sasaran:

  1. Pastikan pengguna Anda mendapatkan versi terbaru yang tersedia. Jika Anda mengubah sesuatu, versi tersebut harus segera ditampilkan
  2. Lakukan #1 saat mengambil sesedikit mungkin dari jaringan

Dalam arti luas, Anda hanya ingin mengirimkan perubahan terkecil kepada klien saat mereka memuat situs Anda lagi. Selain itu, menyusun situs Anda untuk memastikan distribusi perubahan yang paling efisien adalah hal yang menantang (lebih lanjut tentang hal tersebut di bawah dan di video).

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

Latar belakang

Sebagai developer web, kita semua terbiasa dengan ide memiliki "cache yang sudah tidak berlaku". Namun, kita tahu, hampir secara naluri, alat yang tersedia untuk mengatasi hal ini: melakukan "refresh hard", atau membuka jendela samaran, atau menggunakan beberapa kombinasi alat developer browser untuk menghapus data situs.

Pengguna biasa di internet tidak memiliki kemewahan yang sama. Jadi, meskipun kami memiliki beberapa sasaran inti untuk memastikan pengguna menikmati waktu yang menyenangkan dengan pemuatan kedua, sebaiknya pastikan mereka tidak mengalami waktu yang buruk atau terjebak. (Tonton video jika Anda ingin mendengar saya menceritakan bagaimana situs web.dev/live hampir terhambat.)

Untuk sedikit latar belakang, alasan "cache usang" sebenarnya adalah default era 1999 untuk penyimpanan cache. Hal ini bergantung pada header Last-Modified:

Diagram yang menunjukkan berapa lama aset yang berbeda di-cache oleh browser pengguna
Aset yang dibuat pada waktu yang berbeda (berwarna abu-abu) akan disimpan dalam cache untuk waktu yang berbeda, sehingga pemuatan kedua dapat memperoleh kombinasi aset baru dan yang di-cache

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

Dulu, hal ini memang merupakan ide yang baik, tetapi mengingat sifat situs web yang sangat terintegrasi saat ini, perilaku default ini berarti ada kemungkinan untuk masuk ke suatu keadaan ketika pengguna memiliki file yang dirancang untuk rilis yang berbeda dari situs web Anda (mis., JS dari rilis hari Selasa, dan CSS dari rilis hari Jumat), semua karena file tersebut tidak diperbarui pada waktu yang sama persis.

Jalur yang terang

Default modern untuk penyimpanan cache adalah tidak melakukan penyimpanan ke cache sama sekali, dan menggunakan CDN untuk membawa konten Anda dekat dengan 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 secara geografis dekat dengan setiap pengguna akhir.

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

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

Pada dasarnya, pernyataan ini menyatakan; file valid untuk waktu yang singkat dan Anda harus memvalidasinya dari jaringan sebelum dapat menggunakannya lagi (jika tidak, file ini hanya "disarankan").

Proses validasi ini relatif murah dalam hal byte yang ditransfer—jika file gambar besar tidak berubah, browser akan menerima respons 304 kecil—tetapi memerlukan latensi karena pengguna tetap harus masuk ke jaringan untuk mencari tahu. Dan ini adalah kelemahan utama dari pendekatan ini. Hal ini dapat bekerja sangat baik untuk orang-orang yang memiliki koneksi cepat di dunia pertama, dan di mana 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.

Terlepas dari itu, 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 pada file firebase.json Anda:

"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 menyarankan ini sebagai {i>default<i} yang masuk akal, itulah saja—defaultnya! Baca terus untuk mengetahui cara menerapkan dan meningkatkan versi default.

URL dengan sidik jari

Dengan menyertakan hash konten file atas nama aset, gambar, dan lainnya yang ditayangkan di situs, Anda dapat memastikan bahwa file tersebut akan selalu memiliki konten yang unik—hal ini akan menghasilkan file bernama sitecode.af12de.js, misalnya. Saat server merespons permintaan file ini, Anda dapat dengan aman memerintahkan browser pengguna akhir untuk menyimpannya dalam cache untuk waktu yang lama dengan mengonfigurasinya menggunakan header ini:

Cache-Control: max-age=31536000,immutable

Nilai ini adalah tahun, dalam detik. Dan menurut spesifikasinya, nilai ini pada dasarnya sama dengan "forever".

Yang penting, jangan membuat hash ini secara manual karena terlalu banyak pekerjaan manual. Anda dapat menggunakan alat seperti Webpack, Rollup, dan sebagainya untuk melakukannya. Pastikan untuk membaca selengkapnya tentang hal tersebut di Laporan Alat.

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

Terlepas dari pendekatan situs Anda terhadap cache, file dengan sidik jari semacam ini sangat berharga untuk situs apa pun yang mungkin Anda buat. Sebagian besar situs tidak berubah pada setiap rilis.

Tentu saja, kami tidak dapat mengganti nama halaman yang 'ramah' dan ditampilkan kepada pengguna dengan cara ini: mengganti nama file index.html menjadi index.abcd12.html—itu tidak mungkin, Anda tidak dapat memberi tahu 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 kemungkinan tengah.

Jalan tengah

Jelas ada ruang untuk jalan tengah dalam {i>caching<i}. Saya telah menyajikan dua opsi ekstrem; cache never, atau cache forever. Dan akan ada sejumlah file yang mungkin ingin Anda simpan dalam cache untuk sementara waktu, seperti URL "ramah" seperti yang saya sebutkan di atas.

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

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

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

Jika Anda berhati-hati, hal ini mungkin tidak memengaruhi Anda. Namun secara luas, penting untuk diingat bahwa situs Anda—saat di-cache oleh pengguna akhir—tidak lagi hanya ada di server Anda. Namun, konfigurasi ini mungkin ada di bagian di dalam cache browser pengguna akhir Anda.

Secara umum, sebagian besar panduan terkait cache akan membahas setelan semacam ini—apakah Anda perlu menyimpan cache selama satu jam, beberapa jam, dan seterusnya. Untuk menyiapkan jenis cache ini, gunakan header seperti ini (yang disimpan dalam cache selama 3.600 detik atau satu jam):

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

Satu poin terakhir. Jika Anda membuat konten tepat waktu yang biasanya hanya dapat diakses oleh pengguna satu kali—seperti artikel berita!—menurut saya, konten ini tidak boleh di-cache, dan Anda harus menggunakan default yang logis di atas. Menurut saya, kita sering melebih-lebihkan nilai caching daripada 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 meliputi:

  • Secara umum, cari aset yang tidak memengaruhi orang lain

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

    • Pengguna Anda mungkin tidak akan mengunjungi satu artikel pun lebih dari beberapa kali, jadi jangan menyimpan foto atau banner besar di cache selamanya dan menyia-nyiakan penyimpanan
  • Aset yang merepresentasikan sesuatu yang memiliki masa aktif

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

Ringkasan

Ketika pengguna memuat situs Anda untuk kedua kalinya, Anda sudah memiliki kepercayaan diri—mereka ingin kembali dan mendapatkan lebih banyak dari apa yang Anda tawarkan. Pada tahap ini, bukan hanya mengurangi waktu pemuatan tersebut, dan Anda memiliki banyak opsi yang tersedia untuk memastikan bahwa browser hanya melakukan pekerjaan yang diperlukan untuk memberikan pengalaman yang cepat dan terbaru.

Penyimpanan dalam cache bukanlah konsep baru di web, tetapi mungkin hal ini memerlukan setelan default yang wajar. Pertimbangkan untuk menggunakan salah satu strategi penyimpanan dalam cache yang lebih baik saat Anda membutuhkannya. Terima kasih sudah membaca.

Lihat juga

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