Back-forward cache

Back-forward cache (atau bfcache) adalah pengoptimalan browser yang memungkinkan navigasi mundur dan maju secara instan. Fitur ini meningkatkan pengalaman penjelajahan secara signifikan, terutama bagi pengguna dengan jaringan atau perangkat yang lebih lambat.

Sebagai developer web, Anda harus memahami cara mengoptimalkan halaman untuk bfcache, sehingga pengguna dapat memperoleh manfaatnya.

Kompatibilitas browser

Semua browser utama menyertakan bfcache, termasuk Chrome sejak versi 96, Firefox, dan Safari.

Dasar-dasar bfcache

Dengan back/forward cache (bfcache), alih-alih menghancurkan halaman saat pengguna keluar, kita menunda penghancuran dan menjeda eksekusi JS. Jika pengguna segera kembali, kami akan menampilkan halaman lagi dan melanjutkan eksekusi JS. Hal ini menghasilkan navigasi halaman yang hampir instan bagi pengguna.

Berapa kali Anda mengunjungi situs dan mengklik link untuk membuka halaman lain, tetapi menyadari bahwa halaman tersebut bukan yang Anda inginkan dan mengklik tombol kembali? Pada saat itu, bfcache dapat membuat perbedaan besar dalam seberapa cepat halaman sebelumnya dimuat:

Tanpa bfcache yang diaktifkan Permintaan baru dimulai untuk memuat halaman sebelumnya, dan, bergantung pada seberapa baik halaman tersebut telah dioptimalkan untuk kunjungan berulang, browser mungkin harus mendownload ulang, mem-parsing ulang, dan mengeksekusi ulang beberapa (atau semua) resource yang baru saja didownloadnya.
Dengan bfcache diaktifkan Memuat halaman sebelumnya pada dasarnya instan, karena seluruh halaman dapat dipulihkan dari memori, tanpa harus membuka jaringan sama sekali.

Tonton video tentang cara kerja bfcache ini untuk memahami peningkatan kecepatan yang dapat diberikannya pada navigasi:

Penggunaan bfcache membuat halaman dimuat jauh lebih cepat selama navigasi mundur dan maju.

Dalam video tersebut, contoh dengan bfcache jauh lebih cepat daripada contoh tanpa bfcache.

bfcache tidak hanya mempercepat navigasi, tetapi juga mengurangi penggunaan data, karena resource tidak perlu didownload lagi.

Data penggunaan Chrome menunjukkan bahwa 1 dari 10 navigasi di desktop dan 1 dari 5 di perangkat seluler adalah kembali atau maju. Dengan bfcache yang diaktifkan, browser dapat menghilangkan transfer data dan waktu yang dihabiskan untuk memuat miliaran halaman web setiap harinya.

Cara kerja "cache"

"Cache" yang digunakan oleh bfcache berbeda dengan cache HTTP, yang memainkan perannya sendiri dalam mempercepat navigasi berulang. bfcache adalah snapshot seluruh halaman dalam memori, termasuk heap JavaScript, sedangkan cache HTTP hanya berisi respons untuk permintaan yang dibuat sebelumnya. Karena sangat jarang semua permintaan yang diperlukan untuk memuat halaman dipenuhi dari cache HTTP, kunjungan berulang menggunakan pemulihan bfcache selalu lebih cepat daripada navigasi non-bfcache yang paling dioptimalkan sekalipun.

Membekukan halaman untuk berpotensi mengaktifkannya kembali nanti melibatkan beberapa kerumitan dalam hal cara terbaik untuk mempertahankan kode yang sedang berlangsung. Misalnya, bagaimana Anda menangani panggilan setTimeout() yang mencapai waktu tunggu habis saat halaman berada di bfcache?

Jawabannya adalah browser menjeda timer yang tertunda atau promise yang belum terselesaikan untuk halaman di bfcache, termasuk hampir semua tugas yang tertunda di antrean tugas JavaScript, dan melanjutkan tugas pemrosesan jika halaman dipulihkan dari bfcache.

Dalam beberapa kasus, seperti untuk waktu tunggu dan janji, risiko ini cukup rendah, tetapi dalam kasus lain, hal ini dapat menyebabkan perilaku yang membingungkan atau tidak terduga. Misalnya, jika browser menjeda tugas yang diperlukan sebagai bagian dari transaksi IndexedDB, hal ini dapat memengaruhi tab lain yang terbuka di origin yang sama, karena database IndexedDB yang sama dapat diakses oleh beberapa tab secara bersamaan. Akibatnya, browser umumnya tidak akan mencoba menyimpan halaman dalam cache di tengah transaksi IndexedDB atau saat menggunakan API yang dapat memengaruhi halaman lain.

Untuk mengetahui detail selengkapnya tentang cara berbagai penggunaan API memengaruhi kelayakan bfcache halaman, lihat Mengoptimalkan halaman untuk bfcache.

bfcache dan iframe

Jika halaman berisi iframe sematan, iframe itu sendiri tidak memenuhi syarat secara terpisah untuk bfcache. Misalnya, jika Anda membuka URL lain dalam iframe, konten sebelumnya tidak akan masuk ke bfcache dan jika Anda kembali, browser akan "kembali" dalam iframe, bukan dalam frame utama, tetapi navigasi kembali dalam iframe tidak akan menggunakan bfcache.

Namun, saat frame utama dipulihkan dari bfcache, iframe sematan akan dipulihkan seperti saat halaman memasuki bfcache.

Frame utama juga dapat diblokir agar tidak menggunakan bfcache jika iframe sematan menggunakan API yang memblokir hal ini. Permissions Policy yang ditetapkan pada frame utama atau penggunaan atribut sandbox dapat digunakan untuk menghindari hal ini.

bfcache dan Aplikasi Web Satu Halaman (SPA)

Karena bfcache berfungsi dengan navigasi yang dikelola browser, bfcache tidak berfungsi untuk "navigasi ringan" dalam aplikasi web satu halaman (SPA). Namun, bfcache masih dapat membantu saat kembali ke SPA daripada melakukan inisialisasi ulang aplikasi tersebut sepenuhnya dari awal.

API untuk mengamati bfcache

Meskipun bfcache adalah pengoptimalan yang dilakukan browser secara otomatis, developer tetap perlu mengetahui kapan hal itu terjadi agar mereka dapat mengoptimalkan halaman untuk bfcache dan menyesuaikan metrik atau pengukuran performa yang sesuai.

Peristiwa utama yang digunakan untuk mengamati bfcache adalah peristiwa transisi halaman pageshow dan pagehide, yang didukung oleh sebagian besar browser.

Peristiwa Siklus Proses Halaman yang lebih baru—freeze dan resume—juga dikirim saat halaman masuk atau keluar dari bfcache, serta dalam beberapa situasi lain, misalnya, saat tab latar belakang dibekukan untuk meminimalkan penggunaan CPU. Peristiwa ini hanya didukung di browser berbasis Chromium.

Mengamati saat halaman dipulihkan dari bfcache

Peristiwa pageshow aktif tepat setelah peristiwa load, saat halaman pertama kali dimuat dan setiap kali halaman dipulihkan dari bfcache. Peristiwa pageshow memiliki properti persisted, yang bernilai true jika halaman dipulihkan dari bfcache dan false jika tidak. Anda dapat menggunakan properti persisted untuk membedakan pemuatan halaman reguler dari pemulihan bfcache. Contoh:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('This page was restored from the bfcache.');
  } else {
    console.log('This page was loaded normally.');
  }
});

Di browser yang mendukung Page Lifecycle API, peristiwa resume akan aktif saat halaman dipulihkan dari bfcache (tepat sebelum peristiwa pageshow) dan saat pengguna membuka kembali tab latar belakang yang dibekukan. Jika ingin memperbarui status halaman setelah dibekukan (termasuk halaman di bfcache), Anda dapat menggunakan peristiwa resume, tetapi jika ingin mengukur rasio hit bfcache situs, Anda harus menggunakan peristiwa pageshow. Dalam beberapa kasus, Anda mungkin perlu menggunakan keduanya.

Untuk mengetahui detail praktik terbaik pengukuran bfcache, lihat Pengaruh bfcache terhadap pengukuran performa dan analisis.

Mengamati saat halaman memasuki bfcache

Peristiwa pagehide dipicu saat halaman dibatalkan pemuatannya atau saat browser mencoba memasukkannya ke dalam bfcache.

Peristiwa pagehide juga memiliki properti persisted. Jika nilainya false, Anda dapat yakin bahwa halaman tersebut tidak akan segera masuk ke bfcache. Namun, persisted menjadi true tidak menjamin bahwa halaman akan di-cache. Artinya, browser bermaksud untuk meng-cache halaman, tetapi mungkin ada faktor lain yang membuatnya tidak dapat di-cache.

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('This page *might* be entering the bfcache.');
  } else {
    console.log('This page will unload normally and be discarded.');
  }
});

Demikian pula, peristiwa freeze diaktifkan segera setelah peristiwa pagehide jika persisted adalah true, tetapi itu hanya berarti browser bermaksud untuk meng-cache halaman. Mungkin masih harus menghapusnya karena sejumlah alasan yang dijelaskan nanti.

Mengoptimalkan halaman untuk bfcache

Tidak semua halaman disimpan dalam bfcache, dan meskipun halaman disimpan di sana, halaman tersebut tidak akan tetap berada di sana tanpa batas waktu. Developer harus memahami apa yang membuat halaman memenuhi syarat (dan tidak memenuhi syarat) untuk bfcache guna memaksimalkan rasio hit cache.

Bagian berikut menguraikan praktik terbaik untuk memastikan browser dapat menyimpan halaman Anda dalam cache.

Jangan pernah menggunakan peristiwa unload

Cara paling penting untuk mengoptimalkan bfcache di semua browser adalah dengan tidak pernah menggunakan peristiwa unload. Sama sekali!

Peristiwa unload menimbulkan masalah bagi browser karena mendahului bfcache dan banyak halaman di internet beroperasi berdasarkan asumsi (yang wajar) bahwa halaman tidak akan terus ada setelah peristiwa unload diaktifkan. Hal ini menimbulkan tantangan karena banyak halaman tersebut juga dibuat dengan asumsi bahwa peristiwa unload akan diaktifkan setiap kali pengguna keluar, yang tidak lagi benar (dan sudah lama tidak benar).

Jadi, browser menghadapi dilema, mereka harus memilih antara sesuatu yang dapat meningkatkan pengalaman pengguna—tetapi juga dapat merusak halaman.

Di desktop, Chrome dan Firefox telah memilih untuk membuat halaman tidak memenuhi syarat untuk bfcache jika halaman tersebut menambahkan pemroses unload, yang lebih tidak berisiko, tetapi juga mendiskualifikasi banyak halaman. Safari akan mencoba meng-cache beberapa halaman dengan pemroses peristiwa unload, tetapi untuk mengurangi potensi kerusakan, Safari tidak akan menjalankan peristiwa unload saat pengguna keluar dari halaman, sehingga peristiwa tersebut menjadi sangat tidak dapat diandalkan.

Di perangkat seluler, Chrome dan Safari akan mencoba menyimpan halaman dalam cache dengan pemroses peristiwa unload karena risiko kerusakan lebih rendah karena peristiwa unload selalu sangat tidak dapat diandalkan di perangkat seluler. Firefox memperlakukan halaman yang menggunakan unload sebagai tidak memenuhi syarat untuk bfcache, kecuali di iOS, yang mengharuskan semua browser menggunakan mesin rendering WebKit, sehingga berperilaku seperti Safari.

Daripada menggunakan peristiwa unload, gunakan peristiwa pagehide. Peristiwa pagehide aktif di semua kasus saat peristiwa unload aktif, dan juga aktif saat halaman dimasukkan ke dalam bfcache.

Faktanya, Lighthouse memiliki audit no-unload-listeners, yang akan memperingatkan developer jika ada JavaScript di halaman mereka (termasuk dari library pihak ketiga) yang menambahkan pemroses peristiwa unload.

Karena ketidakandalannya, dan dampak performa untuk bfcache, Chrome berencana untuk menghentikan penggunaan peristiwa unload.

Menggunakan Kebijakan Izin untuk mencegah penggunaan handler pelepasan muatan di halaman

Situs yang tidak menggunakan pengendali peristiwa unload dapat memastikan pengendali peristiwa ini tidak ditambahkan dengan menggunakan Kebijakan Izin.

Permissions-Policy: unload=()

Tindakan ini juga mencegah pihak ketiga atau ekstensi memperlambat situs dengan menambahkan pengendali penghapus muatan dan membuat situs tidak memenuhi syarat untuk bfcache.

Hanya tambahkan pemroses beforeunload secara bersyarat

Peristiwa beforeunload tidak akan membuat halaman Anda tidak memenuhi syarat untuk bfcache di bfcache browser modern, tetapi sebelumnya peristiwa ini membuat halaman Anda tidak memenuhi syarat dan masih tidak dapat diandalkan, jadi hindari penggunaannya kecuali benar-benar diperlukan.

Namun, tidak seperti peristiwa unload, ada penggunaan yang sah untuk beforeunload. Misalnya, saat Anda ingin memperingatkan pengguna bahwa mereka memiliki perubahan yang belum disimpan yang akan hilang jika mereka keluar dari halaman. Dalam hal ini, sebaiknya Anda hanya menambahkan pemroses beforeunload saat pengguna memiliki perubahan yang belum disimpan, lalu menghapusnya segera setelah perubahan yang belum disimpan disimpan.

Larangan
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
Kode ini menambahkan pemroses beforeunload tanpa syarat.
Anjuran
function beforeUnloadListener(event) {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  window.addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  window.removeEventListener('beforeunload', beforeUnloadListener);
});
Kode ini hanya menambahkan pemroses beforeunload saat diperlukan (dan menghapusnya saat tidak diperlukan).

Meminimalkan penggunaan Cache-Control: no-store

Cache-Control: no-store adalah header HTTP yang dapat ditetapkan server web pada respons yang menginstruksikan browser untuk tidak menyimpan respons dalam cache HTTP apa pun. Digunakan untuk resource yang berisi informasi pengguna sensitif, seperti halaman di balik login.

Meskipun bfcache bukan cache HTTP, secara historis, saat Cache-Control: no-store disetel di resource halaman itu sendiri (bukan subresource), browser memilih untuk tidak menyimpan halaman di bfcache sehingga halaman yang menggunakan Cache-Control: no-store mungkin tidak memenuhi syarat untuk bfcache. Kami sedang berupaya mengubah perilaku ini untuk Chrome dengan cara yang menjaga privasi.

Karena Cache-Control: no-store membatasi kelayakan halaman untuk bfcache, setelan ini hanya boleh ditetapkan di halaman yang berisi informasi sensitif yang tidak boleh di-cache dalam bentuk apa pun.

Untuk halaman yang harus selalu menyajikan konten terbaru—dan konten tersebut tidak berisi informasi sensitif—gunakan Cache-Control: no-cache atau Cache-Control: max-age=0. Petunjuk ini menginstruksikan browser untuk memvalidasi ulang konten sebelum menayangkannya, dan tidak memengaruhi kelayakan bfcache halaman.

Perhatikan bahwa saat dipulihkan dari bfcache, halaman dipulihkan dari memori, bukan dari cache HTTP. Akibatnya, arahan seperti Cache-Control: no-cache atau Cache-Control: max-age=0 tidak diperhitungkan, dan tidak ada validasi ulang yang terjadi sebelum konten ditampilkan kepada pengguna.

Namun, hal ini masih cenderung memberikan pengalaman pengguna yang lebih baik karena pemulihan bfcache bersifat instan dan—karena halaman tidak berada di bfcache terlalu lama—kemungkinan konten sudah tidak berlaku sangat kecil. Namun, jika konten Anda berubah setiap menit, Anda dapat mengambil pembaruan menggunakan peristiwa pageshow, seperti yang diuraikan di bagian berikutnya.

Memperbarui data yang tidak valid atau sensitif setelah pemulihan bfcache

Jika situs Anda menyimpan status pengguna—terutama informasi pengguna yang sensitif—data tersebut harus diperbarui atau dihapus setelah halaman dipulihkan dari bfcache.

Misalnya, jika pengguna membuka halaman checkout, lalu memperbarui keranjang belanjanya, navigasi kembali berpotensi menampilkan informasi yang sudah tidak berlaku jika halaman yang tidak aktif dipulihkan dari bfcache.

Contoh lain yang lebih penting adalah jika pengguna logout dari situs di komputer publik dan pengguna berikutnya mengklik tombol kembali. Hal ini berpotensi mengekspos data pribadi yang diasumsikan pengguna telah dihapus saat mereka logout.

Untuk menghindari situasi seperti ini, sebaiknya selalu perbarui halaman setelah peristiwa pageshow jika event.persisted adalah true:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Do any checks and updates to the page
  }
});

Meskipun idealnya Anda akan memperbarui konten di tempat, untuk beberapa perubahan, Anda mungkin ingin memuat ulang sepenuhnya. Kode berikut memeriksa keberadaan cookie khusus situs dalam peristiwa pageshow dan memuat ulang jika cookie tidak ditemukan:

window.addEventListener('pageshow', (event) => {
  if (event.persisted && !document.cookie.match(/my-cookie)) {
    // Force a reload if the user has logged out.
    location.reload();
  }
});

Pemuatan ulang memiliki keunggulan yang akan tetap mempertahankan histori (untuk memungkinkan navigasi maju), tetapi pengalihan mungkin lebih tepat dalam beberapa kasus.

Iklan dan pemulihan bfcache

Anda mungkin tergoda untuk mencoba menghindari penggunaan bfcache untuk menayangkan kumpulan iklan baru pada setiap navigasi kembali/maju. Namun, selain berdampak pada performa, perilaku tersebut juga diragukan dapat menghasilkan engagement iklan yang lebih baik. Pengguna mungkin melihat iklan yang ingin mereka klik lagi, tetapi karena memuat ulang, bukan memulihkan dari bfcache, mereka tidak dapat melakukannya. Menguji skenario ini—idealnya dengan pengujian A/B—penting dilakukan sebelum membuat asumsi.

Untuk situs yang ingin memperbarui iklan saat pemulihan bfcache, memperbarui iklan saja pada peristiwa pageshow saat event.persisted adalah true memungkinkan hal ini terjadi tanpa memengaruhi performa halaman. Hubungi penyedia iklan Anda, tetapi berikut adalah salah satu contoh cara melakukannya dengan Tag Penerbitan Google.

Menghindari referensi window.opener

Di browser lama, jika halaman dibuka menggunakan window.open() dari link dengan target=_blank, tanpa menentukan rel="noopener", halaman pembuka akan memiliki referensi ke objek jendela halaman yang dibuka.

Selain menimbulkan risiko keamanan, halaman dengan referensi window.opener yang tidak null tidak dapat dimasukkan dengan aman ke bfcache, karena dapat merusak halaman apa pun yang mencoba mengaksesnya.

Oleh karena itu, sebaiknya hindari pembuatan referensi window.opener. Anda dapat melakukannya dengan menggunakan rel="noopener" jika memungkinkan (perhatikan, ini sekarang menjadi default di semua browser modern). Jika situs Anda memerlukan pembukaan jendela dan mengontrolnya melalui window.postMessage() atau langsung mereferensikan objek jendela, baik jendela yang dibuka maupun pembuka tidak akan memenuhi syarat untuk bfcache.

Tutup koneksi yang terbuka sebelum pengguna keluar dari halaman

Seperti yang disebutkan sebelumnya, saat halaman disimpan di bfcache, halaman akan menjeda semua tugas JavaScript terjadwal dan melanjutkannya saat halaman dikeluarkan dari cache.

Jika tugas JavaScript terjadwal ini hanya mengakses DOM API—atau API lain yang diisolasi hanya ke halaman saat ini—maka menjeda tugas ini saat halaman tidak terlihat oleh pengguna tidak akan menyebabkan masalah apa pun.

Namun, jika tugas ini terhubung ke API yang juga dapat diakses dari halaman lain di origin yang sama (misalnya: IndexedDB, Web Locks, WebSockets), hal ini dapat menimbulkan masalah karena menjeda tugas ini dapat mencegah kode di tab lain berjalan.

Akibatnya, beberapa browser tidak akan mencoba menempatkan halaman di bfcache dalam skenario berikut:

Jika halaman Anda menggunakan salah satu API ini, sebaiknya tutup koneksi dan hapus atau batalkan koneksi pengamat selama peristiwa pagehide atau freeze. Dengan begitu, browser dapat menyimpan halaman dengan aman tanpa risiko memengaruhi tab lain yang terbuka.

Kemudian, jika halaman dipulihkan dari bfcache, Anda dapat membuka kembali atau menyambungkan kembali ke API tersebut selama peristiwa pageshow atau resume.

Contoh berikut menunjukkan cara memastikan bahwa halaman yang menggunakan IndexedDB memenuhi syarat untuk bfcache dengan menutup koneksi terbuka di pemroses peristiwa pagehide:

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('keyval');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => resolve(req.result);
    });
  }
  return dbPromise;
}

// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
  if (dbPromise) {
    dbPromise.then(db => db.close());
    dbPromise = null;
  }
});

// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());

Uji untuk memastikan halaman Anda dapat di-cache

Chrome DevTools dapat membantu Anda menguji halaman untuk memastikan halaman dioptimalkan untuk bfcache, dan mengidentifikasi masalah yang dapat mencegah halaman memenuhi syarat.

Untuk menguji halaman:

  1. Buka halaman di Chrome.
  2. Di DevTools, buka Application -> Back-forward Cache.
  3. Klik tombol Run Test. Kemudian, DevTools mencoba menutup lalu membuka untuk menentukan apakah halaman dapat dipulihkan dari bfcache.
Panel back-forward cache di DevTools
Panel Back-forward Cache di DevTools.

Jika pengujian berhasil, panel akan melaporkan "Dipulihkan dari back-forward cache".

DevTools melaporkan bahwa halaman berhasil dipulihkan dari bfcache
Halaman yang berhasil dipulihkan.

Jika tidak berhasil, panel akan menunjukkan alasannya. Jika alasannya adalah sesuatu yang dapat Anda tangani sebagai developer, panel akan menandainya sebagai Dapat Ditindaklanjuti.

DevTools melaporkan kegagalan memulihkan halaman dari bfcache
Uji bfcache yang gagal dengan hasil yang dapat ditindaklanjuti.

Dalam contoh ini, penggunaan pemroses peristiwa unload membuat halaman tidak memenuhi syarat untuk bfcache. Anda dapat memperbaikinya dengan beralih dari unload ke pagehide:

Anjuran
window.addEventListener('pagehide', ...);
Larangan
window.addEventListener('unload', ...);

Lighthouse 10.0 juga menambahkan audit bfcache, yang melakukan pengujian serupa. Untuk mengetahui informasi selengkapnya, lihat dokumen audit bfcache.

Pengaruh bfcache terhadap pengukuran analisis dan performa

Jika Anda menggunakan alat analisis untuk mengukur kunjungan ke situs Anda, Anda mungkin melihat penurunan jumlah total tayangan halaman yang dilaporkan saat Chrome mengaktifkan bfcache untuk lebih banyak pengguna.

Faktanya, Anda mungkin sudah kurang melaporkan tayangan halaman dari browser lain yang menerapkan bfcache, karena banyak library analisis populer tidak mengukur pemulihan bfcache sebagai tayangan halaman baru.

Untuk menyertakan pemulihan bfcache dalam jumlah tayangan halaman, tetapkan pemroses untuk peristiwa pageshow dan periksa properti persisted.

Contoh berikut menunjukkan cara melakukannya dengan Google Analytics. Alat analisis lainnya kemungkinan menggunakan logika yang serupa:

// Send a pageview when the page is first loaded.
gtag('event', 'page_view');

window.addEventListener('pageshow', (event) => {
  // Send another pageview if the page is restored from bfcache.
  if (event.persisted) {
    gtag('event', 'page_view');
  }
});

Mengukur rasio cache ditemukan bfcache

Anda juga dapat mengukur apakah bfcache digunakan, untuk membantu mengidentifikasi halaman yang tidak menggunakan bfcache. Hal ini dapat dilakukan dengan mengukur jenis navigasi untuk pemuatan halaman:

// Send a navigation_type when the page is first loaded.
gtag('event', 'page_view', {
   'navigation_type': performance.getEntriesByType('navigation')[0].type;
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Send another pageview if the page is restored from bfcache.
    gtag('event', 'page_view', {
      'navigation_type': 'back_forward_cache';
    });
  }
});

Hitung rasio hit bfcache Anda menggunakan jumlah navigasi back_forward dan navigasi back_forward_cache.

Penting untuk menyadari bahwa ada sejumlah skenario, di luar kontrol pemilik situs, saat navigasi Kembali/Maju tidak akan menggunakan bfcache, termasuk:

  • saat pengguna keluar dari browser dan memulainya lagi
  • saat pengguna menduplikasi tab
  • saat pengguna menutup tab dan membukanya kembali

Dalam beberapa kasus ini, jenis navigasi asli dapat dipertahankan oleh beberapa browser dan dengan demikian dapat menampilkan jenis back_forward meskipun ini bukan navigasi Kembali/Maju.

Bahkan tanpa pengecualian tersebut, bfcache akan dihapus setelah jangka waktu tertentu untuk menghemat memori.

Jadi, pemilik situs tidak boleh mengharapkan rasio hit bfcache 100% untuk semua navigasi back_forward. Namun, mengukur rasio ini dapat berguna untuk mengidentifikasi halaman yang mencegah penggunaan bfcache untuk proporsi tinggi navigasi maju dan mundur.

Tim Chrome telah menambahkan NotRestoredReasons API untuk membantu memaparkan alasan halaman tidak menggunakan bfcache, sehingga developer dapat meningkatkan rasio hit bfcache mereka. Tim Chrome juga telah menambahkan jenis navigasi ke CrUX sehingga memungkinkan Anda melihat jumlah navigasi bfcache meskipun tanpa mengukurnya sendiri.

Pengukuran performa

bfcache juga dapat memengaruhi metrik performa yang dikumpulkan di lapangan secara negatif, khususnya metrik yang mengukur waktu pemuatan halaman.

Karena navigasi bfcache memulihkan halaman yang ada, bukan memulai pemuatan halaman baru, total jumlah pemuatan halaman yang dikumpulkan akan berkurang saat bfcache diaktifkan. Namun, yang penting adalah pemuatan halaman yang digantikan oleh pemulihan bfcache kemungkinan merupakan beberapa pemuatan halaman tercepat dalam set data Anda. Hal ini karena navigasi kembali dan maju, menurut definisinya, adalah kunjungan berulang, dan pemuatan halaman berulang umumnya lebih cepat daripada pemuatan halaman dari pengunjung pertama kali (karena penyimpanan dalam cache HTTP, seperti yang disebutkan sebelumnya).

Hasilnya adalah lebih sedikit pemuatan halaman cepat dalam set data Anda, yang kemungkinan akan memiringkan distribusi menjadi lebih lambat—meskipun performa yang dialami pengguna mungkin telah meningkat.

Ada beberapa cara untuk mengatasi masalah ini. Salah satunya adalah memberi anotasi pada semua metrik pemuatan halaman dengan jenis navigasi masing-masing: navigate, reload, back_forward, atau prerender. Dengan begitu, Anda dapat terus memantau performa dalam jenis navigasi ini, meskipun distribusi keseluruhan cenderung negatif. Sebaiknya gunakan pendekatan ini untuk metrik pemuatan halaman yang tidak berfokus pada pengguna seperti Time to First Byte (TTFB).

Untuk metrik yang berfokus pada pengguna seperti Core Web Vitals, opsi yang lebih baik adalah melaporkan nilai yang secara lebih akurat merepresentasikan pengalaman pengguna.

Dampak pada Core Web Vitals

Data Web Inti mengukur pengalaman pengguna di halaman web dalam berbagai dimensi (kecepatan pemuatan, interaktivitas, stabilitas visual), dan karena pengguna mengalami pemulihan bfcache sebagai navigasi yang lebih cepat daripada pemuatan halaman penuh, penting agar metrik Data Web Inti mencerminkan hal ini. Bagaimanapun juga, pengguna tidak peduli apakah bfcache diaktifkan atau tidak, mereka hanya peduli bahwa navigasinya cepat.

Alat yang mengumpulkan dan melaporkan metrik Core Web Vitals, seperti Laporan Pengalaman Pengguna Chrome, memperlakukan pemulihan bfcache sebagai kunjungan halaman terpisah dalam set datanya. Meskipun tidak ada API performa web khusus untuk mengukur metrik ini setelah pemulihan bfcache, Anda dapat memperkirakan nilainya menggunakan API web yang ada:

  • Untuk Largest Contentful Paint (LCP), gunakan selisih antara stempel waktu peristiwa pageshow dan stempel waktu frame yang dilukis berikutnya, karena semua elemen dalam frame akan dilukis pada waktu yang sama. Dalam kasus pemulihan bfcache, LCP dan FCP sama.
  • Untuk Interaction to Next Paint (INP), terus gunakan Performance Observer yang ada, tetapi reset nilai INP saat ini ke 0.
  • Untuk Pergeseran Tata Letak Kumulatif (CLS), terus gunakan Performance Observer yang ada, tetapi reset nilai CLS saat ini ke 0.

Untuk mengetahui detail selengkapnya tentang pengaruh bfcache terhadap setiap metrik, lihat halaman panduan metrik Core Web Vitals masing-masing. Untuk contoh spesifik tentang cara menerapkan versi bfcache dari metrik ini, lihat PR yang menambahkannya ke library JS web-vitals.

Library JavaScript web-vitals mendukung pemulihan bfcache dalam metrik yang dilaporkannya.

Referensi Tambahan