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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

bfcache और iframe

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

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

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

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

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

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

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

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

देखें कि किसी पेज को बैक-कैश मेमोरी से कब वापस लाया गया है

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

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

पेज लाइफ़साइकल एपीआई के साथ काम करने वाले ब्राउज़र में resume इवेंट तब ट्रिगर होता है, जब पेजों को बैक-कैश मेमोरी से वापस लाया जाता है (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 में सेव नहीं होते. भले ही, कोई पेज वहां सेव हो जाए, लेकिन वह हमेशा के लिए वहां नहीं रहेगा. यह ज़रूरी है कि डेवलपर यह समझें कि किस वजह से पेज, कैश मेमोरी में सेव होने की दर ज़्यादा से ज़्यादा बढ़ा सकते हैं. इसके लिए, यह ज़रूरी है कि किन वजहों से पेज को bfकैश मेमोरी में सेव किया जा सकता है और किन चीज़ों के लिए इस्तेमाल नहीं किया जा सकता.

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

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

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

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

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

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

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

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

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

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

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

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

Permission-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 का इस्तेमाल नहीं किया जा सकेगा.

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

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

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

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

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

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

इसके बाद, अगर पेज को बैक-कैश मेमोरी से वापस लाया जाता है, तो 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 से किसी पेज को वापस लाने में हुई समस्या की जानकारी
बीएफ़कैश मेमोरी की जांच में गड़बड़ी हुई, जिस पर कार्रवाई की जा सकती है.

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

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

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

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

अगर अपनी साइट पर आने वाले लोगों की संख्या मेज़र करने के लिए किसी आंकड़े वाले टूल का इस्तेमाल किया जाता है, तो आपको रिपोर्ट किए गए पेज व्यू की कुल संख्या में कमी दिख सकती है. इसकी वजह यह है कि Chrome, ज़्यादा उपयोगकर्ताओं के लिए 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 के रिस्टोर से बदले जा रहे पेज लोड, आपके डेटासेट में सबसे तेज़ पेज लोड में से कुछ हो सकते थे. ऐसा इसलिए होता है, क्योंकि बैक और फ़ॉरवर्ड नेविगेशन, दोबारा विज़िट करने वाले लोगों के लिए होते हैं. आम तौर पर, दोबारा विज़िट करने वाले लोगों के लिए पेज लोड होने में, पहली बार विज़िट करने वाले लोगों के मुकाबले कम समय लगता है. ऐसा एचटीटीपी कैश मेमोरी की वजह से होता है, जैसा कि पहले बताया गया है.

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

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

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

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

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

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

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

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

web-vitals JavaScript लाइब्रेरी, रिपोर्ट की जाने वाली मेट्रिक में बीएफ़कैश मेमोरी को वापस लाने की सुविधा देती है.

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