Topik temu duga representatif

Temu Duga Frontend: Bagaimana Back/Forward Cache Berfungsi dan Bagaimana Anda Menyahpepijat Ketiadaan Padanan (Misses)?

FrontendSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Halaman pembayaran e-dagang kadangkala kembali serta-merta selepas Kembali (Back) dengan borang dan keadaan JavaScript kekal utuh, tetapi boleh memaparkan troli lapuk atau sesi yang telah dilog keluar. Navigasi Kembali yang lain pula memuatkan semula dokumen. Terangkan cara back/forward cache pelayar berfungsi dan reka pelan rentas pelayar untuk mengesan pemulihan, mengesahkan semula keadaan sensitif, melepaskan dan menyambung semula sumber, mendiagnosis ketiadaan padanan, dan mengukur hasilnya tanpa hanya melumpuhkan pengoptimuman tersebut.

Prompt dan senario yang berkenaan

Halaman pembayaran e-dagang berkelakuan berbeza merentasi navigasi sejarah. Kadangkala Kembali memulihkan DOM yang tepat, nilai borang, kedudukan tatal, dan timbunan JavaScript hampir serta-merta. Snapshot yang dipulihkan itu boleh mengandungi jumlah troli lapuk atau sesi yang telah dilog keluar dalam tab lain. Pada masa lain, Kembali mencipta dokumen baharu dan menjalankan laluan pemuatan biasa. Pasukan telah menggunakan istilah "cache pelayar" untuk menggambarkan semua hasil ini dan telah mempertimbangkan untuk melumpuhkan caching secara menyeluruh.

Terangkan bagaimana back/forward cache, atau bfcache, berbeza daripada cache HTTP dan cache penghala SPA. Kemudian reka pelan kitaran hayat dan penyahpepijatan yang:

  • mengesan pemulihan bfcache yang disahkan secara berasingan daripada pemuatan dokumen biasa;
  • mengesahkan semula pengesahan (authentication), troli, dan keadaan sensitif lain sebelum membenarkan tindakan yang membawa kesan;
  • melepaskan sumber semasa halaman disembunyikan dan menyambungkannya semula tepat sekali selepas pemulihan;
  • mencari penghalang kelayakan dalam halaman, bingkai anak (child frames), dan kod pihak ketiga;
  • mengukur penjelajahan sejarah, pemulihan yang disahkan, ketiadaan padanan (misses), dan sebab sekatan mengikut versi pelayar;
  • mengekalkan faedah prestasi apabila ia serasi dengan dasar keselamatan produk.

Soalan ini terpakai kepada temu duga frontend kanan, prestasi web, platform pelayar, dan seni bina frontend. Ia menguji sama ada calon boleh menaakul tentang dokumen yang dijeda, bukan sekadar menghafal pengepala cache.

Perkara yang dinilai oleh penemu duga

Pertama, calon harus membezakan tiga mekanisme yang berasingan. Cache HTTP menyimpan respons yang boleh diguna semula dan menggunakan peraturan permintaan, kesegaran, dan pengesahan semula. bfcache boleh mengekalkan keseluruhan halaman rentas dokumen dalam ingatan, termasuk DOM dan timbunan JavaScript miliknya, kemudian menjeda dan menyambungnya semula untuk penjelajahan sejarah sesi. Penghala klien boleh mengekalkan data aplikasi atau UI untuk navigasi lembut (soft navigation) tanpa mencipta atau memulihkan dokumen yang diuruskan oleh pelayar. Mengosongkan satu cache bukanlah diagnosis untuk yang lain.

Kedua, calon mesti memahami bukti kitaran hayat. pageshow juga dicetuskan pada pemuatan awal, jadi peristiwa itu sahaja bukan bukti. Peristiwa pageshow yang nilai persisted miliknya ialah true mengesahkan bahawa dokumen telah dipulihkan daripada cache seperti bfcache. Pada pagehide, persisted: true bermaksud pelayar berhasrat untuk mengekalkan halaman; ia tidak menjamin halaman akan kekal dicache atau dipulihkan kemudian.

Ketiga, jawapan yang kukuh menganggap pemulihan sebagai sempadan ketepatan. Pemasa dan nilai dalam ingatan disambung semula dari saat yang lebih awal. Keizinan (authorization) masih menjadi hak milik pelayan, dan keadaan sensitif harus disahkan semula pada pemulihan yang disahkan. Sambungan langsung, pemegang pangkalan data, pemerhati, dan kunci mungkin perlu ditutup atau diputuskan sambungannya sebelum navigasi dan dibuka semula selepas kembali. Kod penyambungan semula mestilah idempoten.

Keempat, calon harus menyahpepijat dengan bukti dan bukannya senarai penghalang universal. Kelayakan berubah mengikut pelayar, versi, bingkai, API, dasar respons, tekanan ingatan, dan senario navigasi. Chrome DevTools boleh menjalankan ujian bfcache terpencil dan mengklasifikasikan penghalang. Jika disokong, PerformanceNavigationTiming.notRestoredReasons menambah bukti lapangan dan pepohon bingkai, tetapi rentetan sebabnya mungkin berubah dan butiran rentas asal (cross-origin) boleh ditopengkan.

Akhir sekali, calon harus mentakrifkan hasil yang boleh diukur. Penjelajahan sejarah yang dilaporkan sebagai back_forward bukanlah bukti hit bfcache dengan sendirinya. Hit yang disahkan datang daripada pageshow.persisted. Ketiadaan padanan ialah pemuatan dokumen baharu yang dicapai melalui penjelajahan sejarah, dan puncanya harus disegmenkan dan bukannya diteka. Matlamatnya adalah liputan pemulihan selamat yang lebih tinggi tanpa tindakan sesi lapuk, sambungan pendua, atau analitik yang terherot.

Soalan untuk dijelaskan sebelum menjawab

  • Navigasi manakah yang terlibat? Adakah ia navigasi dokumen penuh, pertukaran laluan SPA lembut, muat semula, tab yang dibuka semula, atau penjelajahan Kembali/Maju sebenar dalam tab yang sama?
  • Apakah yang boleh kekal dengan selamat? Draf borang dan kedudukan tatal mungkin diingini; pengesahan, harga, inventori, kebenaran, dan token sekali guna memerlukan peraturan kesegaran yang berwibawa.
  • Apakah yang diperlukan oleh dasar respons? Sesetengah halaman mengandungi data yang dilarang oleh dasar produk daripada disimpan dalam snapshot halaman. Keperluan itu diutamakan berbanding kadar hit.
  • Sumber manakah yang kekal aktif? WebSocket inventori, sambungan IndexedDB, Kunci Web, tangkapan media, pemerhati, dan skrip pihak ketiga boleh menjejaskan ketepatan atau kelayakan.
  • Pelayar dan versi manakah yang penting? Output DevTools dan notRestoredReasons bukanlah kontrak yang boleh alih (portable). Uji matriks pelayar yang disokong dengan navigasi sejarah sebenar.
  • Adakah bingkai anak wujud? Anak asal yang sama (same-origin) boleh mendedahkan pepohon penghalang terperinci. Bingkai rentas asal mungkin hanya memaparkan maklumat bertopeng, memerlukan pengasingan vendor atau pembiakan minimum.
  • Apakah yang dimaksudkan dengan "lapuk"? Tentukan usia maksimum yang boleh diterima dan tindakan yang disekat semasa pengesahan semula gagal.
  • Bagaimanakah analitik dikira? Tentukan sama ada halaman yang dipulihkan ialah paparan halaman, navigasi, atau kedua-duanya, kemudian elakkan satu pemulihan daripada memancarkan peristiwa pendua.
  • Apakah get kejayaan? Jejaki nisbah pemulihan yang disahkan antara penjelajahan sejarah yang boleh diperhatikan, sebab terlepas, kependaman pemulihan, kegagalan pengesahan semula, pencegahan tindakan lapuk, dan kiraan sumber pendua.

Rangka kerja jawapan 30 saat

"Saya memisahkan bfcache daripada cache HTTP dan penghala: ia menjeda dokumen untuk navigasi sejarah yang diuruskan pelayar. Saya mengesahkan hit hanya dengan pageshow.persisted, menggunakan pagehide untuk pembersihan idempoten tanpa mengandaikan pemulihan. Semasa pemulihan, saya mengesahkan semula sesi, troli, harga, dan kebenaran sebelum tindakan sensitif, kemudian menyambung semula sumber sekali. Saya menghasilkan semula ketiadaan padanan dalam pelayar yang disokong, menggunakan panel bfcache Chrome dan data notRestoredReasons yang tersedia, serta mengasingkan metrik lapangan mengikut pelayar dan laluan. Saya mengoptimumkan halaman yang selamat sambil memastikan pengesahan pelayan dan dasar tanpa snapshot kekal berwibawa."

Panduan mendalam langkah demi langkah

Langkah 1: Modelkan empat laluan yang boleh diperhatikan

Mulakan dengan hasil dan bukannya pengepala:

LaluanDokumen baharu?Bukti utamaPengendalian yang diperlukan
Navigasi awal atau pautanYapageshow.persisted === false; jenis navigasi biasanya navigateMulakan keadaan dan sumber
Muat semulaYapageshow.persisted === false; jenis navigasi reloadJalankan laluan pemuatan biasa
Penjelajahan sejarah dengan muat semulaYapageshow.persisted === false; jenis navigasi back_forwardRekodkan ketiadaan padanan bfcache dan periksa sebabnya
Pemulihan bfcache yang disahkanTidakpageshow.persisted === trueSahkan semula keadaan sensitif dan sambung semula dengan selamat

Jenis navigasi menerangkan cara dokumen baharu dicapai. Ia tidak dapat mengesahkan hit bfcache kerana hit menyambung semula dokumen lama. Walau bagaimanapun, ia boleh mengenal pasti pemuatan baharu yang disebabkan oleh penjelajahan sejarah dan oleh itu menyumbang kepada penyebut ketiadaan padanan. Permulaan semula pelayar, penduaan tab, dan aliran buka semula boleh mengaburkan isyarat ini, jadi metrik lapangan harus membawa pelayar, versi, laluan, dan senario jika tersedia.

bfcache juga berbeza daripada pengesahan semula HTTP. Pada pemulihan, pelayar menyambung semula halaman dalam ingatan; Cache-Control: no-cache tidak memaksa pengesahan rangkaian sebelum piksel dipaparkan. Jika kandungan yang dipulihkan mesti terkini, aplikasi melakukan semakan disasarkan selepas pageshow. Navigasi lembut SPA mengubah sejarah dan UI di dalam dokumen yang sama; bfcache menjadi relevan apabila dokumen itu sendiri ditinggalkan dan kemudian dipulihkan.

Langkah 2: Jadikan kerja kitaran hayat idempoten dan selamat dipulihkan

Pusatkan pemilikan sambungan. Pembersihan mungkin diikuti oleh dokumen baharu, pemulihan, atau tiada pulangan langsung. Persediaan boleh dijalankan selepas pemuatan awal dan selepas beberapa pemulihan, jadi kedua-dua operasi mesti bertoleransi terhadap pengulangan.

js
let liveSocket = null;

function connectLiveUpdates() {
  if (liveSocket) return;
  liveSocket = new WebSocket("wss://shop.example/live-cart");
}

function disconnectLiveUpdates() {
  liveSocket?.close();
  liveSocket = null;
}

async function revalidateSensitiveState() {
  const response = await fetch("/api/session-snapshot", {
    cache: "no-store",
    credentials: "same-origin",
  });

  if (response.status === 401) {
    location.replace("/login");
    return false;
  }
  if (!response.ok) {
    showRetryState();
    return false;
  }
  renderSessionState(await response.json());
  return true;
}

window.addEventListener("pagehide", disconnectLiveUpdates);

window.addEventListener("pageshow", async (event) => {
  reportNavigation(event.persisted ? "bfcache_restore" : "document_load");
  if (event.persisted && !(await revalidateSensitiveState())) return;
  connectLiveUpdates();
});

Titik akhir pelayan sampel kekal sebagai pihak berkuasa. UI harus melumpuhkan pembayaran semasa keadaan sensitif yang dipulihkan sedang diperiksa, dan semakan yang gagal harus menunjukkan keadaan cuba semula dan bukannya mempercayai snapshot secara senyap. Permintaan pembayaran sebelah pelayan masih mesti mengesahkan semula pengguna dan mengira semula harga serta inventori.

Jangan gunakan unload untuk pembersihan kritikal. Ia tidak boleh dipercayai dan boleh menyebabkan halaman tidak layak dalam sesetengah pelayar. Utamakan pagehide untuk pembersihan kitaran hayat halaman dan gunakan visibilitychange apabila keperluannya adalah keterlihatan dan bukannya navigasi. Elakkan daripada menjadikan freeze dan resume khusus Chromium sebagai satu-satunya laluan ketepatan.

Langkah 3: Diagnosis ketiadaan padanan daripada pembiakan tempatan kepada pemilikan

Hasilkan semula satu laluan dengan urutan deterministik: buka secara langsung, wujudkan keadaan yang berkaitan, ikuti pautan biasa ke dokumen kedua, kemudian gunakan butang Kembali pelayar. Elakkan sambungan (extensions) dan alatan pembangunan dalam larian kawalan kerana ia boleh mengubah tingkah laku kitaran hayat. Ulangi dengan pengepala respons pengeluaran dan skrip pihak ketiga.

Dalam Chrome, jalankan ujian Back/forward cache pada panel Application. Catatkan sama ada hasilnya boleh diambil tindakan, menunggu sokongan pelayar, atau tidak boleh diambil tindakan, dan kembangkan atribusi bingkai. Jika pendengar unload muncul, cari sama ada kod pihak pertama atau vendor yang mendaftarkannya. Jika dasar respons, sambungan terbuka, transaksi aktif, kunci, API media, atau bingkai muncul, kurangkannya kepada ciri sebenar terkecil yang menghasilkan semula hasil tersebut.

Jika disokong, periksa notRestoredReasons pada dokumen baharu yang dicapai melalui penjelajahan sejarah yang terlepas. Kekalkan hierarki dan nilai sebab yang dikembalikan sebagai data diagnostik, bukan logik aplikasi. Jangan kod keras rentetan sebab yang tepat, anggap setiap pelayar mendedahkan sifat tersebut, atau tafsirkan null sahaja sebagai hit yang disahkan. Butiran anak rentas asal boleh ditopengkan untuk privasi; uji vendor yang dibenamkan secara berasingan atau alih keluarnya dalam eksperimen terkawal untuk mewujudkan sebab akibat.

Selesaikan satu pemilik pada satu masa, jalankan semula ujian terpencil, kemudian sahkan keseluruhan laluan. Menutup sambungan IndexedDB atau WebSocket pada pagehide, mengalih keluar pengendali unload, dan mengehadkan bingkai pihak ketiga ialah contoh hipotesis; keputusan pelayar menentukan sama ada perubahan tersebut benar-benar mempengaruhi kelayakan.

Langkah 4: Sahkan ketepatan dan prestasi di lapangan

Pancarkan satu peristiwa untuk setiap pageshow. persisted: true ialah pemulihan yang disahkan. Untuk pemuatan dokumen baharu, lampirkan jenis Navigation Timing; back_forward mengenal pasti penjelajahan sejarah yang boleh diperhatikan yang terlepas bfcache. Pastikan peristiwa tersebut saling eksklusif. Tambah keluarga laluan, pelayar, versi, keadaan pengesahan, dan kohort eksperimen tanpa merekodkan kandungan halaman peribadi.

Ukur sekurang-kurangnya:

  1. pemulihan yang disahkan dibahagikan dengan penjelajahan sejarah yang boleh diperhatikan, disegmenkan mengikut pelayar dan laluan;
  2. kiraan ketiadaan padanan dan keluarga sebab sekatan yang disokong, termasuk kes bertopeng dan tidak tersedia;
  3. kependaman pemulihan-ke-cat-seterusnya (restore-to-next-paint) dan pemulihan-ke-keadaan-sensitif-interaktif;
  4. kegagalan pengesahan semula sesi, kebenaran, troli, harga, dan inventori;
  5. percubaan pembayaran yang disekat sementara keadaan yang dipulihkan belum disahkan;
  6. kesan sampingan soket, pemerhati, analitik, dan pemasa pendua selepas kitaran Kembali/Maju berulang;
  7. regresi ingatan dan kegagalan yang dapat dilihat oleh pengguna, kerana memaksimumkan kadar hit bukanlah satu-satunya objektif.

Jalankan kitaran sejarah berulang, log keluar dalam tab lain, ubah troli di tempat lain, tamatkan tempoh token sekali guna, gagalkan titik akhir pengesahan semula, dan uji bingkai rentas asal. Uji versi Chrome, Firefox, dan Safari dalam skop. Panel Chrome tempatan membuktikan satu kes terkawal; telemetri pengeluaran membuktikan pengedaran, dan penegasan produk membuktikan keselamatan.

Contoh jawapan berkualiti tinggi

"Laluan serta-merta ialah bfcache: pelayar mengekalkan keseluruhan dokumen pembayaran dan timbunan JavaScript miliknya, menjedanya, dan menyambungnya semula semasa navigasi sejarah sesi. Cache HTTP hanya menyimpan respons, manakala penghala klien mengendalikan navigasi lembut dalam dokumen langsung. Saya akan melabelkan laluan terlebih dahulu. pageshow.persisted === true mengesahkan pemulihan. Dokumen baharu yang jenis Navigation Timing miliknya ialah back_forward mewakili penjelajahan sejarah yang tidak memulihkan halaman ini daripada bfcache. pagehide.persisted === true hanyalah niat pelayar untuk mencache, jadi saya tidak akan menggunakannya sebagai rekod hit."

"Pada pagehide, saya menutup sumber yang tidak sepatutnya kekal aktif, seperti soket troli dan sebarang transaksi terbuka, menggunakan pembersihan idempoten. Pada setiap pageshow, saya memastikan sumber disambungkan tepat sekali. Untuk pemulihan yang disahkan, saya menyekat pembayaran buat sementara waktu, mengambil snapshot sesi dan troli yang berwibawa, mengemas kini UI, dan mengubah hala semasa log keluar. API pembayaran masih menyemak keizinan, harga semasa, dan inventori, jadi timbunan yang disambung semula tidak akan dapat membenarkan pembelian. Saya mengira pemulihan sekali untuk analitik dan bukannya menjalankan semula semua kesan pemuatan awal."

"Untuk ketiadaan padanan, saya menghasilkan semula laluan dokumen penuh yang tepat dengan pengepala dan vendor pengeluaran. Dalam Chrome saya menjalankan ujian bfcache panel Application, mengembangkan pemilikan bingkai, dan membetulkan punca yang boleh diambil tindakan satu demi satu. Pada versi Chromium yang disokong, saya mengumpul notRestoredReasons untuk pemuatan sejarah yang terlepas, mengekalkan kes bertopeng dan tidak diketahui serta tidak pernah mencabangkan tingkah laku produk pada teks sebab. Saya kemudian menguji matriks Chrome, Firefox, dan Safari yang disokong kerana kelayakan berubah mengikut pelaksanaan dan senario."

"Get pelancaran ialah nisbah pemulihan disahkan yang lebih tinggi dengan kependaman kembali yang lebih rendah, manakala tindakan sesi lapuk, sambungan pendua, dan penduaan analitik kekal sifar dalam ujian. Saya mengasingkan ketiadaan padanan dan kegagalan pengesahan semula mengikut laluan dan pelayar. Jika dasar menyatakan halaman yang mengandungi data peribadi tertentu tidak boleh disnapshot sama sekali, saya mengekalkan sekatan itu dan mengoptimumkan halaman sekeliling dan bukannya menggadaikan keselamatan demi kadar hit."

Kesilapan biasa dan penambahbaikan

  • Memanggil setiap laluan kembali sebagai "cache pelayar" → Respons HTTP, snapshot keseluruhan dokumen, dan keadaan penghala mematuhi peraturan yang berbeza → Namakan mekanisme dan kumpulkan bukti khusus mekanisme.
  • Menggunakan pageshow sahaja sebagai bukti → Ia juga dicetuskan pada pemuatan dokumen awal → Perlukan event.persisted === true untuk pemulihan yang disahkan.
  • Menganggap pagehide.persisted sebagai hit masa hadapan → Pelayar kemudiannya boleh menyingkirkan halaman atau memilih laluan lain → Gunakan ia hanya untuk membimbing pembersihan yang selamat; rekodkan hit semasa pemulihan.
  • Menganggap back_forward bermaksud bfcache → Ia boleh menerangkan dokumen baharu yang dimuatkan oleh penjelajahan sejarah → Gabungkan jenis navigasi untuk ketiadaan padanan dengan pageshow.persisted untuk hit.
  • Melumpuhkan semua caching untuk membetulkan UI lapuk → Ini menyembunyikan pepijat kitaran hayat dan mengorbankan navigasi serta-merta → Sahkan semula medan sensitif dan pastikan keizinan pelayan kekal berwibawa.
  • Memuatkan semula setiap halaman yang dipulihkan → Muat semula menyeluruh membuang pengoptimuman dan boleh berulang jika gagal → Segarkan hanya keadaan berwibawa, simpan muat semula atau ubah hala untuk keadaan tidak sah yang ditakrifkan.
  • Menghafal senarai penghalang kekal → Kelayakan dan nama sebab berubah merentasi enjin dan versi → Gunakan ujian pelayar, pengesanan ciri, dan bukti lapangan.
  • Meletakkan pembersihan dalam unload Peristiwa ini tidak boleh dipercayai dan boleh menghalang kelayakan → Gunakan pagehide, ditambah peristiwa keterlihatan apabila keperluan produk adalah keterlihatan.
  • Menyambung semula pada setiap peristiwa kitaran hayat → pageshow, resume, dan kesan rangka kerja boleh mencipta soket atau pemerhati pendua → Berikan setiap sumber satu pemilik yang idempoten.
  • Mempercayai satu pas DevTools sahaja → Ia tidak merangkumi vendor sebenar, tekanan ingatan, pelayar, atau perubahan sesi → Gabungkan ujian terkawal, matriks pelayar, RUM, dan aliran produk yang bertentangan (adversarial).

Soalan susulan

Adakah Cache-Control: no-cache memaksa pengesahan sebelum pemulihan bfcache?

Tidak. Pemulihan bfcache menyambung semula dokumen dalam ingatan dan bukannya memenuhi permintaan sumbernya melalui cache HTTP, jadi arahan pengesahan semula HTTP tidak berjalan sebelum halaman yang dipulihkan dipaparkan. Gunakan pageshow.persisted untuk mencetuskan semakan kesegaran yang disasarkan. Jika dasar melarang penyimpanan snapshot halaman sama sekali, gunakan dasar respons dan pelayar yang sesuai, dengan menerima bahawa kelayakan boleh berbeza-beza mengikut pelaksanaan.

Adakah PerformanceNavigationTiming.type === "back_forward" merupakan isyarat hit?

Tidak. Ia memberitahu dokumen yang baru dibuat bahawa ia dicapai melalui penjelajahan sejarah. Pemulihan bfcache yang disahkan menyambung semula dokumen sedia ada dan dikenal pasti dengan pageshow.persisted === true. Kira pemuatan back_forward baharu sebagai ketiadaan padanan yang boleh diperhatikan, tertakluk kepada keanehan pelayar seperti senario permulaan semula atau tab yang dibuka semula, dan segmenkan telemetri sewajarnya.

Bagaimana jika notRestoredReasons tiada, null, atau bertopeng?

Anggap tiada sebagai tidak disokong, null sebagai tidak mencukupi dengan sendirinya, dan bertopeng sebagai kategori diagnostik yang memelihara privasi. Sahkan hit dengan peristiwa peralihan halaman. Untuk ketiadaan padanan, hasilkan semula secara tempatan, periksa output DevTools yang tersedia, asingkan bingkai anak dan skrip pihak ketiga, dan kekalkan baldi tidak diketahui daripada mencipta punca palsu.

Bagaimanakah analitik harus mengendalikan halaman yang dipulihkan?

Pilih definisi produk terlebih dahulu. Jika pemulihan dikira sebagai paparan halaman, pancarkan satu peristiwa daripada pageshow.persisted dan elakkan memainkan semula instrumentasi pemuatan awal. Sertakan medan jenis navigasi supaya penganalisis boleh memisahkan pemuatan dokumen daripada pemulihan. Tetapkan semula akumulator prestasi berskop lawatan jika sesuai, dan uji kitaran Kembali/Maju yang berulang untuk penduaan.

Patutkah halaman pembayaran yang disahkan menggunakan bfcache?

Hanya jika dasar keselamatan membenarkan snapshot halaman dan laluan pemulihan boleh dijadikan selamat. Semasa pemulihan, sahkan semula sesi dan data yang penting, sekat tindakan sensitif sehingga semakan selesai, dan pastikan keizinan sebelah pelayan serta pengesahan harga adalah mandatori. Jika kandungan peribadi tidak boleh kekal boleh dipulihkan dalam sejarah, kuat kuasakan dasar tersebut dan fokuskan pengoptimuman bfcache pada laluan yang kurang sensitif.

Sumber awam

Soalan berkaitan