बैक-फ़ॉरवर्ड कैश मेमोरी

बैक/फ़ॉरवर्ड कैश मेमोरी (या bfcache), ब्राउज़र का ऐसा ऑप्टिमाइज़ेशन है जो तुरंत पीछे और आगे जाने की सुविधा देता है. इससे ब्राउज़िंग का अनुभव काफ़ी बेहतर होता है. खास तौर पर, धीमे नेटवर्क या डिवाइस इस्तेमाल करने वाले लोगों के लिए.

वेब डेवलपर के तौर पर, यह समझना ज़रूरी है कि bfcache के लिए अपने पेजों को कैसे ऑप्टिमाइज़ करें, ताकि आपके उपयोगकर्ता इसका फ़ायदा ले सकें.

ब्राउज़र के साथ काम करना

सभी मुख्य ब्राउज़र में bfcache शामिल होता है. इसमें Chrome के वर्शन 96 से लेकर, Firefox और Safari तक शामिल हैं.

bfcache के बारे में बुनियादी बातें

बैक/फ़ॉरवर्ड कैश मेमोरी (bfcache) की मदद से, जब उपयोगकर्ता किसी दूसरे पेज पर जाता है, तो हम पेज को मिटाने की प्रोसेस को रोक देते हैं. साथ ही, JS को एक्सीक्यूट होने से रोक देते हैं. अगर उपयोगकर्ता जल्द ही वापस आता है, तो हम पेज को फिर से दिखाते हैं और JS को फिर से चलाते हैं. इससे, उपयोगकर्ता को पेज पर तुरंत नेविगेट करने की सुविधा मिलती है.

आपने कितनी बार किसी वेबसाइट पर जाकर, किसी दूसरे पेज पर जाने के लिए लिंक पर क्लिक किया है और फिर यह महसूस किया है कि आपको वह पेज नहीं चाहिए और आपने 'वापस जाएं' बटन पर क्लिक किया है? उस दौरान, bfcache की सुविधा से यह फ़र्क़ पड़ सकता है कि पिछला पेज कितनी तेज़ी से लोड होता है:

बिना bfcache चालू पिछले पेज को लोड करने के लिए, एक नया अनुरोध शुरू किया जाता है. साथ ही, इस बात पर निर्भर करता है कि उस पेज को दोबारा विज़िट करने के लिए, कितनी अच्छी तरह से ऑप्टिमाइज़ किया गया है. इसके आधार पर, ब्राउज़र को कुछ (या सभी) संसाधनों को फिर से डाउनलोड करना, फिर से पार्स करना, और फिर से लागू करना पड़ सकता है.
bfcache चालू होने पर पिछले पेज को लोड करना असल में तुरंत होता है, क्योंकि पूरे पेज को मेमोरी से वापस लाया जा सकता है. इसके लिए, नेटवर्क का इस्तेमाल करने की ज़रूरत नहीं होती.

bfcache की सुविधा की मदद से, नेविगेशन को तेज़ी से कैसे इस्तेमाल किया जा सकता है, यह जानने के लिए यह वीडियो देखें:

bfcache का इस्तेमाल करने से, पीछे और आगे नेविगेट करने के दौरान पेज ज़्यादा तेज़ी से लोड होते हैं.

वीडियो में, bfcache का इस्तेमाल करने वाले उदाहरण की तुलना में, बिना bfcache वाले उदाहरण में ज़्यादा समय लगता है.

bfcache, नेविगेशन को तेज़ करने के साथ-साथ डेटा खर्च को भी कम करता है. ऐसा इसलिए होता है, क्योंकि संसाधनों को फिर से डाउनलोड करने की ज़रूरत नहीं पड़ती.

Chrome के इस्तेमाल से जुड़े डेटा से पता चलता है कि डेस्कटॉप पर हर 10 में से एक और मोबाइल पर हर पांच में से एक नेविगेशन, बैक या फ़ॉरवर्ड होता है. bfcache चालू होने पर, ब्राउज़र हर दिन करोड़ों वेब पेजों को लोड करने में लगने वाले समय और डेटा ट्रांसफ़र को खत्म कर सकते हैं!

"कैश मेमोरी" कैसे काम करती है

bfcache का इस्तेमाल किया जाने वाला "कैश", एचटीटीपी कैश से अलग होता है. यह दोबारा नेविगेट करने की प्रोसेस को तेज़ करने में अपनी भूमिका निभाता है. bfcache, मेमोरी में मौजूद पूरे पेज का स्नैपशॉट होता है. इसमें JavaScript ढेर भी शामिल होता है, जबकि एचटीटीपी कैश में सिर्फ़ पहले किए गए अनुरोधों के रिस्पॉन्स होते हैं. किसी पेज को लोड करने के लिए ज़रूरी सभी अनुरोधों को एचटीटीपी कैश मेमोरी से पूरा करना बहुत मुश्किल होता है. इसलिए, bfcache का इस्तेमाल करके, किसी पेज पर दोबारा जाने पर, पेज तेज़ी से खुलता है. यह bfcache का इस्तेमाल किए बिना, सबसे अच्छी तरह से ऑप्टिमाइज़ किए गए नेविगेशन से भी तेज़ होता है.

किसी पेज को बाद में फिर से चालू करने के लिए, उसे फ़्रीज़ करना थोड़ा मुश्किल होता है. ऐसा इसलिए, क्योंकि इस दौरान, चल रहे कोड को सुरक्षित रखने का सबसे सही तरीका ढूंढना पड़ता है. उदाहरण के लिए, setTimeout() कॉल को कैसे मैनेज करें, जब पेज bfcache में हो और टाइम आउट हो गया हो?

इसका जवाब यह है कि ब्राउज़र, bfcache में मौजूद पेजों के लिए, बाकी बचे किसी भी टाइमर या पूरे नहीं किए गए प्रॉमिस को रोक देते हैं. इसमें, JavaScript टास्क की सूचियों में मौजूद, बाकी बचे सभी टास्क भी शामिल हैं. साथ ही, अगर पेज को bfcache से वापस लाया जाता है, तो टास्क को प्रोसेस करना फिर से शुरू कर दिया जाता है.

कुछ मामलों में, जैसे कि टाइम आउट और प्रॉमिस के लिए, इसकी वजह से ज़्यादा जोखिम नहीं होता. हालांकि, अन्य मामलों में इससे भ्रम या अनचाहा व्यवहार हो सकता है. उदाहरण के लिए, अगर ब्राउज़र किसी ऐसे टास्क को रोक देता है जो IndexedDB ट्रांज़ैक्शन के हिस्से के तौर पर ज़रूरी है, तो इससे उसी ऑरिजिन के अन्य खुले टैब पर असर पड़ सकता है. इसकी वजह यह है कि एक ही IndexedDB डेटाबेस को एक साथ कई टैब ऐक्सेस कर सकते हैं. इसलिए, आम तौर पर ब्राउज़र, IndexedDB लेन-देन के बीच में या ऐसे एपीआई का इस्तेमाल करते समय पेजों को कैश मेमोरी में सेव नहीं करते जिनसे दूसरे पेजों पर असर पड़ सकता है.

अलग-अलग एपीआई के इस्तेमाल से, किसी पेज के bfcache की ज़रूरी शर्तों पर क्या असर पड़ता है, इस बारे में ज़्यादा जानने के लिए, bfcache के लिए अपने पेजों को ऑप्टिमाइज़ करना लेख पढ़ें.

bfcache और iframe

अगर किसी पेज में एम्बेड किए गए iframe हैं, तो वे iframe खुद bfcache के लिए ज़रूरी शर्तें पूरी नहीं करते. उदाहरण के लिए, अगर किसी iframe में किसी दूसरे पेज पर नेविगेट करने के बाद वापस आते हैं, तो ब्राउज़र मुख्य फ़्रेम के बजाय iframe में "वापस" जाएगा. हालांकि, iframe में वापस नेविगेट करने पर, bfcache का इस्तेमाल नहीं किया जाएगा.

अगर एम्बेड किए गए iframe में ऐसे एपीआई का इस्तेमाल किया जाता है जो bfcache को ब्लॉक करते हैं, तो मुख्य फ़्रेम को भी bfcache का इस्तेमाल करने से ब्लॉक किया जा सकता है. इस समस्या से बचने के लिए, मुख्य फ़्रेम पर सेट की गई अनुमतियों की नीति या sandbox एट्रिब्यूट का इस्तेमाल किया जा सकता है.

bfcache और एक पेज के ऐप्लिकेशन (एसपीए)

bfcache, ब्राउज़र से मैनेज किए जाने वाले नेविगेशन के साथ काम करता है. इसलिए, यह एक पेज वाले ऐप्लिकेशन (एसपीए) में "सॉफ़्ट नेविगेशन" के लिए काम नहीं करता. हालांकि, किसी एसपीए पर वापस जाने के लिए, bfcache का इस्तेमाल किया जा सकता है. ऐसा करने पर, आपको उस ऐप्लिकेशन को शुरू से फिर से शुरू करने की ज़रूरत नहीं पड़ेगी.

bfcache को देखने के लिए एपीआई

bfcache एक ऐसा ऑप्टिमाइज़ेशन है जो ब्राउज़र अपने-आप करता है. हालांकि, डेवलपर के लिए यह जानना ज़रूरी है कि यह कब हो रहा है, ताकि वे इसके लिए अपने पेजों को ऑप्टिमाइज़ कर सकें और किसी भी मेट्रिक या परफ़ॉर्मेंस मेज़रमेंट में बदलाव कर सकें.

bfcache को मॉनिटर करने के लिए, पेज ट्रांज़िशन इवेंट pageshow और pagehide का इस्तेमाल किया जाता है. ये इवेंट ज़्यादातर ब्राउज़र पर काम करते हैं.

पेज लाइफ़साइकल के नए इवेंट—freeze और resume—जब पेज bfcache में शामिल होते हैं या उससे बाहर निकलते हैं, तब भी भेजे जाते हैं. साथ ही, कुछ अन्य स्थितियों में भी इन्हें भेजा जाता है. उदाहरण के लिए, जब सीपीयू के इस्तेमाल को कम करने के लिए, बैकग्राउंड टैब फ़्रीज़ हो जाता है. ये इवेंट सिर्फ़ Chromium कोड वाले ब्राउज़र में काम करते हैं.

देखें कि bfcache से पेज कब वापस लाया जाता है

pageshow इवेंट, load इवेंट के ठीक बाद ट्रिगर होता है. ऐसा तब होता है, जब पेज पहली बार लोड हो रहा हो और जब भी पेज को bfcache से वापस लाया जाए. pageshow इवेंट में persisted प्रॉपर्टी होती है. अगर पेज को bfcache से वापस लाया गया था, तो यह true होती है. अगर पेज को bfcache से वापस नहीं लाया गया था, तो यह false होती है. persisted प्रॉपर्टी का इस्तेमाल करके, सामान्य पेज लोड और bfcache के रीस्टोर के बीच अंतर किया जा सकता है. उदाहरण के लिए:

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

Page Lifecycle API के साथ काम करने वाले ब्राउज़र में, resume इवेंट तब ट्रिगर होता है, जब पेजों को bfcache से वापस लाया जाता है (pageshow इवेंट से ठीक पहले) और जब कोई उपयोगकर्ता फ़्रीज़ किए गए बैकग्राउंड टैब पर फिर से जाता है. अगर आपको किसी पेज को फ़्रीज़ करने के बाद उसकी स्थिति अपडेट करनी है, तो resume इवेंट का इस्तेमाल करें. इसमें, bfcache में मौजूद पेज भी शामिल हैं. हालांकि, अगर आपको अपनी साइट के bfcache हिट रेट को मेज़र करना है, तो आपको pageshow इवेंट का इस्तेमाल करना होगा. कुछ मामलों में, आपको दोनों का इस्तेमाल करना पड़ सकता है.

bfcache मेज़रमेंट के सबसे सही तरीकों के बारे में जानने के लिए, bfcache का आंकड़े और परफ़ॉर्मेंस मेज़रमेंट पर क्या असर पड़ता है लेख पढ़ें.

देखें कि कोई पेज bfcache में कब जा रहा है

pagehide इवेंट तब ट्रिगर होता है, जब कोई पेज अनलोड होता है या जब ब्राउज़र उसे bfcache में डालने की कोशिश करता है.

pagehide इवेंट में persisted प्रॉपर्टी भी है. अगर यह false है, तो भरोसा किया जा सकता है कि पेज, bfcache में नहीं जाएगा. हालांकि, persisted के true होने से इस बात की गारंटी नहीं मिलती कि पेज को कैश मेमोरी में सेव किया जाएगा. इसका मतलब है कि ब्राउज़र, पेज को कैश मेमोरी में सेव करने की कोशिश कर रहा है. हालांकि, कुछ अन्य वजहों से ऐसा नहीं हो पा रहा है.

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.');
  }
});

इसी तरह, अगर persisted true है, तो freeze इवेंट, pagehide इवेंट के तुरंत बाद ट्रिगर होता है. हालांकि, इसका मतलब सिर्फ़ यह है कि ब्राउज़र पेज को कैश मेमोरी में सेव करने के लिए इस्तेमाल कर रहा है. हालांकि, कई वजहों से उसे इसे खारिज करना पड़ सकता है. इन वजहों के बारे में आगे बताया गया है.

bfcache के लिए अपने पेजों को ऑप्टिमाइज़ करना

सभी पेज, bfcache में सेव नहीं होते. भले ही, कोई पेज वहां सेव हो जाए, लेकिन वह हमेशा के लिए वहां सेव नहीं रहेगा. यह ज़रूरी है कि डेवलपर यह समझें कि कैश मेमोरी में पेज के हिट की दर को बढ़ाने के लिए, कौनसे पेज bfcache का इस्तेमाल कर सकते हैं और कौनसे नहीं.

यहां दिए गए सेक्शन में, सबसे सही तरीके बताए गए हैं. इनकी मदद से, ब्राउज़र आपके पेजों को कैश मेमोरी में सेव कर सकता है.

unload इवेंट का कभी इस्तेमाल न करें

सभी ब्राउज़र में bfcache को ऑप्टिमाइज़ करने का सबसे अहम तरीका यह है कि unload इवेंट का कभी इस्तेमाल न करें. कभी नहीं!

unload इवेंट, ब्राउज़र के लिए समस्या पैदा करता है, क्योंकि यह bfcache से पहले का है. साथ ही, इंटरनेट पर कई पेज इस (उचित) अनुमान के तहत काम करते हैं कि unload इवेंट ट्रिगर होने के बाद, पेज मौजूद नहीं रहेगा. यह एक समस्या है, क्योंकि उनमें से कई पेजों को इस धारणा के साथ भी बनाया गया था कि जब भी कोई उपयोगकर्ता किसी दूसरे पेज पर जाएगा, तब unload इवेंट ट्रिगर होगा. हालांकि, अब ऐसा नहीं है. यह बहुत समय से ऐसा नहीं है.

इसलिए, ब्राउज़र के सामने एक समस्या होती है. उन्हें उपयोगकर्ता अनुभव को बेहतर बनाने वाले विकल्प के बीच से किसी एक को चुनना होता है. हालांकि, ऐसा करने से पेज के क्रैश होने का खतरा भी हो सकता है.

डेस्कटॉप पर, Chrome और Firefox ने पेजों को bfcache के लिए अमान्य कर दिया है. ऐसा तब किया जाता है, जब वे unload लिसनर जोड़ते हैं. यह लिसनर कम जोखिम वाला होता है, लेकिन इससे कई पेजों को अमान्य कर दिया जाता है. Safari, unload इवेंट लिसनर की मदद से कुछ पेजों को कैश मेमोरी में सेव करने की कोशिश करेगा. हालांकि, उपयोगकर्ता के किसी दूसरे पेज पर जाने पर, वह unload इवेंट को नहीं चलाएगा, ताकि पेज के क्रैश होने की संभावना कम हो. इस वजह से, इवेंट पर भरोसा नहीं किया जा सकता.

मोबाइल पर, Chrome और Safari, unload इवेंट लिसनर की मदद से पेजों को कैश मेमोरी में सेव करने की कोशिश करेंगे. ऐसा इसलिए, क्योंकि मोबाइल पर unload इवेंट हमेशा बहुत भरोसेमंद नहीं रहा है. इसलिए, पेज के क्रैश होने का खतरा कम होता है. Firefox, unload का इस्तेमाल करने वाले पेजों को, बैक-फ़ॉरवर्ड कैश मेमोरी की सुविधा के लिए ज़रूरी शर्तें पूरी न करने वाले पेजों के तौर पर मानता है. हालांकि, iOS पर ऐसा नहीं होता. iOS पर सभी ब्राउज़र को WebKit रेंडरिंग इंजन का इस्तेमाल करना होता है. इसलिए, यह Safari की तरह काम करता है.

unload इवेंट के बजाय, pagehide इवेंट का इस्तेमाल करें. pagehide इवेंट उन सभी मामलों में ट्रिगर होता है जहां unload इवेंट ट्रिगर होता है. साथ ही, यह किसी पेज को bfcache में डालने पर भी ट्रिगर होता है.

असल में, Lighthouse में no-unload-listeners ऑडिट होता है. इससे डेवलपर को चेतावनी मिलेगी, अगर उनके पेजों पर कोई JavaScript (इसमें तीसरे पक्ष की लाइब्रेरी से जुड़ा JavaScript भी शामिल है) unload इवेंट लिसनर जोड़ता है.

इसकी भरोसेमंद न होने और bfcache की परफ़ॉर्मेंस पर असर डालने की वजह से, Chrome unload इवेंट को बंद करने की कोशिश कर रहा है.

किसी पेज पर अनलोड हैंडलर के इस्तेमाल को रोकने के लिए, अनुमति नीति का इस्तेमाल करना

unload इवेंट हैंडलर का इस्तेमाल न करने वाली साइटें, अनुमतियों की नीति का इस्तेमाल करके यह पक्का कर सकती हैं कि इन्हें जोड़ा न जाए.

Permissions-Policy: unload=()

इससे तीसरे पक्ष या एक्सटेंशन, अनलोड हैंडलर जोड़कर साइट की स्पीड को धीमा नहीं कर पाते. साथ ही, साइट को bfcache के लिए ज़रूरी शर्तें पूरी करने से रोकते हैं.

सिर्फ़ beforeunload दर्शकों को शर्त के साथ जोड़ना

beforeunload इवेंट की वजह से, आपके पेजों को आधुनिक ब्राउज़र में bfcache के लिए अमान्य नहीं माना जाएगा. हालांकि, पहले ऐसा होता था और अब भी यह भरोसेमंद नहीं है. इसलिए, जब तक ज़रूरी न हो, तब तक इसका इस्तेमाल न करें.

हालांकि, unload इवेंट के उलट, beforeunload का इस्तेमाल सही तरीके से किया जा सकता है. उदाहरण के लिए, जब आपको उपयोगकर्ता को चेतावनी देनी हो कि पेज छोड़ने पर, सेव नहीं किए गए बदलाव मिट जाएंगे. इस मामले में, हमारा सुझाव है कि आप beforeunload दर्शकों को सिर्फ़ तब जोड़ें, जब उपयोगकर्ता ने सेव नहीं किए गए बदलाव किए हों. इसके बाद, सेव नहीं किए गए बदलावों को सेव करने के तुरंत बाद उन्हें हटा दें.

यह न करें
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
यह कोड, beforeunload को बिना किसी शर्त के दर्शक के तौर पर जोड़ता है.
यह करें
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);
});
यह कोड, beforeunload लिसनर को सिर्फ़ तब जोड़ता है, जब ज़रूरत होती है. साथ ही, ज़रूरत न होने पर उसे हटा देता है.

Cache-Control: no-store का इस्तेमाल कम से कम करना

Cache-Control: no-store एक एचटीटीपी हेडर है. वेब सर्वर, रिस्पॉन्स पर इसे सेट कर सकते हैं. इससे ब्राउज़र को यह निर्देश मिलता है कि वह रिस्पॉन्स को किसी भी एचटीटीपी कैश में सेव न करे. इसका इस्तेमाल, उपयोगकर्ता की संवेदनशील जानकारी वाले संसाधनों के लिए किया जाता है. जैसे, लॉगिन करने के बाद दिखने वाले पेज.

हालांकि, bfcache कोई एचटीटीपी कैश मेमोरी नहीं है, लेकिन जब Cache-Control: no-store को पेज के रिसॉर्स पर सेट किया जाता है, तो ब्राउज़र पेज को bfcache में सेव नहीं करते. ऐसा इसलिए होता है, क्योंकि Cache-Control: no-store का इस्तेमाल करने वाले पेज, bfcache की ज़रूरी शर्तें पूरी नहीं करते. Chrome के लिए इस व्यवहार को बदलने पर काम किया जा रहा है. ऐसा, निजता को बनाए रखते हुए किया जा रहा है.

Cache-Control: no-store, किसी पेज को बैक/फ़ॉरवर्ड कैश मेमोरी में सेव करने की सुविधा से रोकता है. इसलिए, इसे सिर्फ़ उन पेजों पर सेट किया जाना चाहिए जिनमें संवेदनशील जानकारी शामिल हो और जहां किसी भी तरह की कैश मेमोरी सेव करना सही न हो.

जिन पेजों पर हमेशा अप-टू-डेट कॉन्टेंट दिखाना ज़रूरी है और जिनमें संवेदनशील जानकारी नहीं है उनके लिए Cache-Control: no-cache या Cache-Control: max-age=0 का इस्तेमाल करें. ये निर्देश, ब्राउज़र को कॉन्टेंट दिखाने से पहले उसकी फिर से पुष्टि करने का निर्देश देते हैं. इनसे, किसी पेज के bfcache की ज़रूरी शर्तों पर कोई असर नहीं पड़ता.

ध्यान दें कि जब किसी पेज को bfcache से वापस लाया जाता है, तो उसे एचटीटीपी कैश मेमोरी से नहीं, बल्कि मेमोरी से वापस लाया जाता है. इस वजह से, Cache-Control: no-cache या Cache-Control: max-age=0 जैसे निर्देशों को ध्यान में नहीं रखा जाता. साथ ही, उपयोगकर्ता को कॉन्टेंट दिखाने से पहले, उसकी फिर से पुष्टि नहीं की जाती.

हालांकि, इससे उपयोगकर्ता को बेहतर अनुभव मिल सकता है. ऐसा इसलिए, क्योंकि bfcache तुरंत वापस आ जाता है. साथ ही, पेज bfcache में ज़्यादा समय तक नहीं रहते. इसलिए, यह संभावना नहीं है कि कॉन्टेंट पुराना हो. हालांकि, अगर आपका कॉन्टेंट हर मिनट बदलता है, तो अगले सेक्शन में बताए गए तरीके से pageshow इवेंट का इस्तेमाल करके, किसी भी अपडेट को फ़ेच किया जा सकता है.

bfcache को वापस लाने के बाद, पुराना या संवेदनशील डेटा अपडेट करना

अगर आपकी साइट पर उपयोगकर्ता की स्थिति सेव की जाती है, खास तौर पर उपयोगकर्ता की संवेदनशील जानकारी, तो bfcache से पेज को वापस लाने के बाद, उस डेटा को अपडेट या मिटाना होगा.

उदाहरण के लिए, अगर कोई उपयोगकर्ता चेकआउट पेज पर जाता है और फिर अपना शॉपिंग कार्ट अपडेट करता है, तो वापस जाने पर पुरानी जानकारी दिख सकती है. ऐसा तब होता है, जब bfcache से पुराना पेज वापस लाया जाता है.

एक और ज़्यादा अहम उदाहरण यह है कि अगर कोई उपयोगकर्ता सार्वजनिक कंप्यूटर पर किसी साइट से साइन आउट करता है और अगला उपयोगकर्ता 'वापस जाएं' बटन पर क्लिक करता है. इससे, निजी डेटा को ऐक्सेस किया जा सकता है. उपयोगकर्ता को लगता है कि लॉग आउट करने पर, यह डेटा मिट जाता है.

इस तरह की स्थितियों से बचने के लिए, अगर event.persisted true है, तो pageshow इवेंट के बाद पेज को हमेशा अपडेट करना अच्छा होता है:

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

आम तौर पर, कॉन्टेंट को अपडेट करने के लिए, उसे बदलने की ज़रूरत नहीं होती. हालांकि, कुछ बदलावों के लिए, आपको कॉन्टेंट को पूरी तरह से रीफ़्रेश करना पड़ सकता है. यहां दिया गया कोड, pageshow इवेंट में साइट-स्पेसिफ़िक कुकी की मौजूदगी की जांच करता है. अगर कुकी नहीं मिलती है, तो उसे फिर से लोड करता है:

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

रीफ़्रेश करने का फ़ायदा यह है कि इससे इतिहास सेव रहेगा (ताकि आगे नेविगेट किया जा सके). हालांकि, कुछ मामलों में रीडायरेक्ट करना ज़्यादा सही हो सकता है.

विज्ञापन और bfcache को वापस लाना

हर बैक/फ़ॉरवर्ड नेविगेशन पर विज्ञापनों का नया सेट दिखाने के लिए, bfcache का इस्तेमाल न करने की कोशिश की जा सकती है. हालांकि, परफ़ॉर्मेंस पर असर पड़ने के साथ-साथ, इस बात पर भी संदेह है कि इस तरह के व्यवहार से विज्ञापन में दर्शकों की दिलचस्पी बढ़ती है या नहीं. हो सकता है कि उपयोगकर्ताओं को कोई ऐसा विज्ञापन दिखे जिस पर क्लिक करने के लिए वे वापस आना चाहते हों. हालांकि, bfcache से उसे वापस लाने के बजाय, उसे फिर से लोड करने पर वे ऐसा नहीं कर पाएंगे. कोई अनुमान लगाने से पहले, इस स्थिति की जांच करना ज़रूरी है. आम तौर पर, A/B टेस्ट से यह जांच की जाती है.

जिन साइटों को bfcache को वापस लाने पर विज्ञापनों को रीफ़्रेश करना है उनके लिए, event.persisted के true होने पर सिर्फ़ pageshow इवेंट पर विज्ञापनों को रीफ़्रेश करने से, पेज की परफ़ॉर्मेंस पर असर पड़े बिना ऐसा किया जा सकता है. अपने विज्ञापन देने वाली कंपनी से संपर्क करें. हालांकि, Google पब्लिशिंग टैग की मदद से ऐसा करने का एक उदाहरण यहां दिया गया है.

window.opener रेफ़रंस से बचना

पुराने ब्राउज़र में, अगर किसी पेज को target=_blank वाले लिंक से window.open() का इस्तेमाल करके खोला गया था, तो खोले गए पेज में, खोले गए पेज के विंडो ऑब्जेक्ट का रेफ़रंस होगा. हालांकि, इसके लिए rel="noopener" की जानकारी देना ज़रूरी नहीं है.

सुरक्षा से जुड़ा जोखिम होने के अलावा, नॉन-नल window.opener रेफ़रंस वाले पेज को bfcache में सुरक्षित तरीके से नहीं डाला जा सकता. ऐसा करने पर, उसे ऐक्सेस करने वाले सभी पेजों में गड़बड़ी हो सकती है.

इसलिए, window.opener रेफ़रंस बनाने से बचना ही बेहतर है. जब भी हो सके, rel="noopener" का इस्तेमाल करके ऐसा किया जा सकता है. ध्यान दें, यह अब सभी आधुनिक ब्राउज़र में डिफ़ॉल्ट रूप से उपलब्ध है. अगर आपकी साइट को कोई विंडो खोलने और उसे window.postMessage() की मदद से कंट्रोल करने या सीधे तौर पर विंडो ऑब्जेक्ट का रेफ़रंस देने की ज़रूरत है, तो खोली गई विंडो या उसे खोलने वाले टैब, दोनों के लिए bfcache का इस्तेमाल नहीं किया जा सकेगा.

उपयोगकर्ता के किसी दूसरे पेज पर जाने से पहले, खुले कनेक्शन बंद करना

जैसा कि पहले बताया गया है, जब किसी पेज को bfcache में रखा जाता है, तो शेड्यूल किए गए सभी JavaScript टास्क रोक दिए जाते हैं. साथ ही, पेज को कैश मेमोरी से हटाने पर, उन्हें फिर से शुरू कर दिया जाता है.

अगर शेड्यूल किए गए ये JavaScript टास्क सिर्फ़ DOM API या सिर्फ़ मौजूदा पेज के लिए अलग किए गए अन्य एपीआई को ऐक्सेस कर रहे हैं, तो पेज के दिखने के दौरान इन टास्क को रोकने से कोई समस्या नहीं होगी.

हालांकि, अगर ये टास्क उन एपीआई से जुड़े हैं जिन्हें उसी ऑरिजिन के दूसरे पेजों से भी ऐक्सेस किया जा सकता है (उदाहरण के लिए: IndexedDB, वेब लॉक, वेबसोकेट), तो समस्या हो सकती है. ऐसा इसलिए, क्योंकि इन टास्क को रोकने से, दूसरे टैब में कोड नहीं चल पाएगा.

इस वजह से, कुछ ब्राउज़र इन स्थितियों में किसी पेज को bfcache में डालने की कोशिश नहीं करेंगे:

  • ऐसे पेज जिनके लिए कोई ओपेन IndexedDB कनेक्शन मौजूद है
  • ऐसे पेज जिन पर fetch() या XMLHttpRequest फ़ंक्शन का इस्तेमाल किया जा रहा हो
  • ऐसे पेज जिन पर WebSocket या WebRTC कनेक्शन खुला हो

अगर आपका पेज इनमें से किसी भी एपीआई का इस्तेमाल कर रहा है, तो हमारा सुझाव है कि आप pagehide या freeze इवेंट के दौरान कनेक्शन बंद कर दें. साथ ही, ऑब्ज़र्वर को हटा दें या डिसकनेक्ट कर दें. इससे ब्राउज़र, पेज को सुरक्षित तरीके से कैश मेमोरी में सेव कर पाता है. साथ ही, इससे खुले हुए अन्य टैब पर कोई असर नहीं पड़ता.

इसके बाद, अगर पेज को bfcache से वापस लाया जाता है, तो pageshow या resume इवेंट के दौरान, उन एपीआई को फिर से खोला जा सकता है या उनसे फिर से कनेक्ट किया जा सकता है.

नीचे दिए गए उदाहरण में, यह पक्का करने का तरीका बताया गया है कि IndexedDB का इस्तेमाल करने वाले पेज, pagehide इवेंट लिसनर में किसी ओपन कनेक्शन को बंद करके, bfcache का इस्तेमाल कर सकते हैं:

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());

यह जांचना कि आपके पेजों को कैश मेमोरी में सेव किया जा सकता है या नहीं

Chrome DevTools की मदद से, अपने पेजों की जांच करके यह पक्का किया जा सकता है कि वे bfcache के लिए ऑप्टिमाइज़ किए गए हैं या नहीं. साथ ही, उन समस्याओं की पहचान की जा सकती है जिनकी वजह से वे ज़रूरी शर्तें पूरी नहीं कर पा रहे हैं.

किसी पेज की जांच करने के लिए:

  1. Chrome में उस पेज पर जाएं.
  2. DevTools में, ऐप्लिकेशन -> बैक-फ़ॉरवर्ड कैश मेमोरी पर जाएं.
  3. जांच करें बटन पर क्लिक करें. इसके बाद, DevTools पेज को bfcache से वापस लाया जा सकता है या नहीं, यह पता लगाने के लिए पेज से बाहर निकलने और फिर वापस आने की कोशिश करता है.
DevTools में बैक-फ़ॉरवर्ड कैश मेमोरी पैनल
DevTools में बैक-फ़ॉरवर्ड कैश मेमोरी पैनल.

अगर जांच पूरी हो जाती है, तो पैनल "बैक-फ़ॉरवर्ड कैश मेमोरी से रीस्टोर किया गया" रिपोर्ट करता है.

DevTools की रिपोर्टिंग से पता चलता है कि किसी पेज को bfcache से वापस लाया गया
बहाल किया गया पेज.

अगर ऐसा नहीं होता है, तो पैनल में इसकी वजह दिखती है. अगर समस्या ऐसी है जिसे डेवलपर के तौर पर ठीक किया जा सकता है, तो पैनल उसे कार्रवाई की जा सकती है के तौर पर मार्क करता है.

DevTools में, bfcache से किसी पेज को वापस लाने में हुई समस्या की जानकारी
कार्रवाई के लिए उपलब्ध नतीजे के साथ, bfcache टेस्ट में हुई गड़बड़ी.

इस उदाहरण में, unload इवेंट लिसनर का इस्तेमाल करने से, पेज को bfcache के लिए अमान्य कर दिया जाता है. इस गड़बड़ी को ठीक करने के लिए, unload की जगह pagehide का इस्तेमाल करें:

यह करें
window.addEventListener('pagehide', ...);
यह न करें
window.addEventListener('unload', ...);

Lighthouse 10.0 में bfcache ऑडिट भी जोड़ा गया है, जो मिलता-जुलता टेस्ट करता है. ज़्यादा जानकारी के लिए, bfcache ऑडिट के दस्तावेज़ देखें.

bfcache से आंकड़ों और परफ़ॉर्मेंस मेज़रमेंट पर क्या असर पड़ता है

अगर अपनी साइट पर आने वाले लोगों की संख्या मेज़र करने के लिए किसी आंकड़े वाले टूल का इस्तेमाल किया जाता है, तो आपको रिपोर्ट किए गए पेज व्यू की कुल संख्या में कमी दिख सकती है. ऐसा इसलिए, क्योंकि Chrome ज़्यादा उपयोगकर्ताओं के लिए bfcache को चालू करता है.

असल में, हो सकता है कि bfcache लागू करने वाले अन्य ब्राउज़र से मिलने वाले पेज व्यू की संख्या पहले से ही कम रिपोर्ट की जा रही हो. इसकी वजह यह है कि कई लोकप्रिय आंकड़े वाली लाइब्रेरी, bfcache के रीस्टोर को नए पेज व्यू के तौर पर मेज़र नहीं करती हैं.

अपने पेज व्यू की संख्या में bfcache के रीस्टोर को शामिल करने के लिए, pageshow इवेंट के लिए लिसनर सेट करें और persisted प्रॉपर्टी की जांच करें.

नीचे दिए गए उदाहरण में, Google Analytics की मदद से ऐसा करने का तरीका बताया गया है. अन्य आंकड़े जुटाने वाले टूल भी इसी तरह के लॉजिक का इस्तेमाल करते हैं:

// 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');
  }
});

bfcache के हिट रेशियो को मेज़र करना

आपके पास यह मेज़र करने का विकल्प भी है कि bfcache का इस्तेमाल किया गया था या नहीं. इससे, उन पेजों की पहचान करने में मदद मिलती है जो bfcache का इस्तेमाल नहीं कर रहे हैं. पेज लोड के लिए नेविगेशन टाइप को मेज़र करके ऐसा किया जा सकता है:

// 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';
    });
  }
});

back_forward नेविगेशन और back_forward_cache नेविगेशन की गिनती का इस्तेमाल करके, अपने bfcache हिट रेशियो का हिसाब लगाएं.

यह समझना ज़रूरी है कि साइट के मालिक के कंट्रोल से बाहर कई स्थितियां होती हैं, जब बैक/फ़ॉरवर्ड नेविगेशन, bfcache का इस्तेमाल नहीं करेगा. इनमें ये स्थितियां शामिल हैं:

  • जब उपयोगकर्ता ब्राउज़र बंद करके उसे फिर से शुरू करता है
  • जब उपयोगकर्ता किसी टैब की डुप्लीकेट कॉपी बनाता है
  • जब उपयोगकर्ता किसी टैब को बंद करके उसे फिर से खोलता है

इनमें से कुछ मामलों में, कुछ ब्राउज़र ओरिजनल नेविगेशन टाइप को सेव कर सकते हैं. इसलिए, हो सकता है कि वे बैक/फ़ॉरवर्ड नेविगेशन न होने के बावजूद, back_forward टाइप दिखाएं.

इन एक्सक्लूज़न के बिना भी, मेमोरी बचाने के लिए bfcache को कुछ समय बाद हटा दिया जाएगा.

इसलिए, वेबसाइट के मालिकों को सभी back_forward नेविगेशन के लिए, 100% bfcache हिट रेशियो की उम्मीद नहीं करनी चाहिए. हालांकि, इनके अनुपात को मेज़र करने से, उन पेजों की पहचान करने में मदद मिल सकती है जहां पेज, बैक और फ़ॉरवर्ड नेविगेशन के ज़्यादातर अनुपात के लिए, bfcache के इस्तेमाल को रोक रहा है.

Chrome की टीम ने NotRestoredReasons एपीआई जोड़ा है. इससे यह पता चलता है कि पेज, bfcache का इस्तेमाल क्यों नहीं करते. इससे डेवलपर, bfcache के हिट रेट को बेहतर बना सकते हैं. Chrome की टीम ने CrUX में नेविगेशन टाइप भी जोड़े हैं. इससे, bfcache नेविगेशन की संख्या को खुद मेज़र किए बिना भी देखा जा सकता है.

परफ़ॉर्मेंस मेज़रमेंट

bfcache, फ़ील्ड में इकट्ठा की गई परफ़ॉर्मेंस मेट्रिक पर भी बुरा असर डाल सकता है. खास तौर पर, उन मेट्रिक पर जिनसे पेज लोड होने में लगने वाले समय का पता चलता है.

bfcache नेविगेशन, नया पेज लोड करने के बजाय मौजूदा पेज को वापस लाते हैं. इसलिए, bfcache चालू होने पर, इकट्ठा किए गए पेज लोड की कुल संख्या कम हो जाएगी. हालांकि, अहम बात यह है कि bfcache के रिस्टोर से बदले जा रहे पेज लोड, आपके डेटासेट में सबसे तेज़ पेज लोड में से कुछ हो सकते थे. ऐसा इसलिए होता है, क्योंकि बैक और फ़ॉरवर्ड नेविगेशन, दोबारा विज़िट करने वाले लोगों के लिए होते हैं. आम तौर पर, दोबारा विज़िट करने वाले लोगों के लिए पेज लोड होने में, पहली बार विज़िट करने वाले लोगों के मुकाबले कम समय लगता है. ऐसा एचटीटीपी कैश मेमोरी की वजह से होता है, जैसा कि पहले बताया गया है.

इस वजह से, आपके डेटासेट में तेज़ी से लोड होने वाले पेजों की संख्या कम हो जाती है. इससे, डिस्ट्रिब्यूशन में देरी हो सकती है. भले ही, उपयोगकर्ता को मिलने वाली परफ़ॉर्मेंस में शायद सुधार हुआ हो!

इस समस्या को हल करने के कुछ तरीके हैं. पहला तरीका, सभी पेज लोड मेट्रिक को उनके नेविगेशन टाइप: navigate, reload, back_forward या prerender के साथ एनोटेट करना है. इससे, इन नेविगेशन टाइप में अपनी परफ़ॉर्मेंस पर नज़र रखी जा सकती है. भले ही, कुल डिस्ट्रिब्यूशन में गिरावट आई हो. हमारा सुझाव है कि टाइम टू फ़र्स्ट बाइट (टीटीएफ़बी) जैसी पेज लोड की ऐसी मेट्रिक के लिए, इस तरीके का इस्तेमाल करें जो उपयोगकर्ता पर आधारित नहीं हैं.

वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी जैसी उपयोगकर्ता-केंद्रित मेट्रिक के लिए, ऐसी वैल्यू रिपोर्ट करना बेहतर विकल्प है जो उपयोगकर्ता के अनुभव को ज़्यादा सटीक तरीके से दिखाती हो.

वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी पर असर

वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी, अलग-अलग डाइमेंशन (लोड होने में लगने वाला समय, इंटरैक्टिविटी, विज़ुअल स्टेबिलिटी) के हिसाब से, किसी वेब पेज पर उपयोगकर्ता के अनुभव का आकलन करती है. साथ ही, उपयोगकर्ताओं को पूरा पेज लोड होने के मुकाबले, bfcache के ज़रिए तेज़ी से नेविगेट करने का अनुभव मिलता है. इसलिए, यह ज़रूरी है कि वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक में इस बात की जानकारी दिखे. आखिरकार, उपयोगकर्ता को इस बात से कोई फ़र्क़ नहीं पड़ता कि bfcache की सुविधा चालू है या नहीं. उन्हें सिर्फ़ इस बात से फ़र्क़ पड़ता है कि नेविगेशन तेज़ी से हुआ या नहीं!

Chrome उपयोगकर्ता अनुभव रिपोर्ट जैसे टूल, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक इकट्ठा करते हैं और उनकी रिपोर्ट बनाते हैं. ये टूल, अपने डेटासेट में bfcache के रीस्टोर को अलग-अलग पेज विज़िट के तौर पर ट्रीट करते हैं. bfcache के वापस आने के बाद, इन मेट्रिक को मेज़र करने के लिए खास वेब परफ़ॉर्मेंस एपीआई उपलब्ध नहीं हैं. हालांकि, मौजूदा वेब एपीआई का इस्तेमाल करके, इनकी वैल्यू का अनुमान लगाया जा सकता है:

  • सबसे बड़े कॉन्टेंटफ़ुल पेंट (एलसीपी) के लिए, pageshow इवेंट के टाइमस्टैंप और पेंट किए गए अगले फ़्रेम के टाइमस्टैंप के बीच के डेल्टा का इस्तेमाल करें. ऐसा इसलिए, क्योंकि फ़्रेम में मौजूद सभी एलिमेंट एक ही समय पर पेंट किए जाएंगे. bfcache को वापस लाने के मामले में, एलसीपी और एफ़सीपी एक ही होते हैं.
  • पेज के रिस्पॉन्स में लगने वाला समय (आईएनपी) के लिए, अपने मौजूदा परफ़ॉर्मेंस ऑब्ज़र्वर का इस्तेमाल जारी रखें. हालांकि, मौजूदा आईएनपी वैल्यू को 0 पर रीसेट करें.
  • कुल लेआउट शिफ़्ट (सीएलएस) के लिए, अपने मौजूदा परफ़ॉर्मेंस ऑब्ज़र्वर का इस्तेमाल जारी रखें. हालांकि, मौजूदा सीएलएस वैल्यू को 0 पर रीसेट करें.

bfcache से हर मेट्रिक पर क्या असर पड़ता है, इस बारे में ज़्यादा जानने के लिए, Core Web Vitals की अलग-अलग मेट्रिक गाइड के पेज देखें. इन मेट्रिक के bfcache वर्शन लागू करने का तरीका जानने के लिए, वेब-विटल्स JS लाइब्रेरी में उन्हें जोड़ने के लिए PR देखें.

वेब-विटल्स JavaScript लाइब्रेरी, रिपोर्ट की जाने वाली मेट्रिक में bfcache को वापस लाने की सुविधा के साथ काम करती है.

अतिरिक्त संसाधन