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

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

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

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

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

बीएफ़कैश के बारे में बुनियादी जानकारी

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

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

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

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

बैक/फ़ॉरवर्ड कैश मेमोरी का इस्तेमाल करने से, पीछे और आगे जाने के दौरान पेज बहुत तेज़ी से लोड होते हैं.

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

bfcache से न सिर्फ़ नेविगेशन की स्पीड बढ़ती है, बल्कि डेटा का इस्तेमाल भी कम होता है. ऐसा इसलिए होता है, क्योंकि संसाधनों को दोबारा डाउनलोड नहीं करना पड़ता.

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

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

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

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

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

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

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

बीएफ़कैश और iframe

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

हालांकि, जब मुख्य फ़्रेम को बैक/फ़ॉरवर्ड कैश मेमोरी से वापस लाया जाता है, तब एम्बेड किए गए iframe को उसी स्थिति में वापस लाया जाएगा जिस स्थिति में पेज को बैक/फ़ॉरवर्ड कैश मेमोरी में सेव किया गया था.

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

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

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

बीएफ़कैश की स्थिति का पता लगाने वाले एपीआई

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

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

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

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

जब पेज लोड हो रहा होता है, तब load इवेंट के ठीक बाद pageshow इवेंट ट्रिगर होता है. साथ ही, जब भी पेज को bfcache से वापस लाया जाता है, तब भी यह इवेंट ट्रिगर होता है. 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.');
  }
});

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

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

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

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

pagehide इवेंट में persisted प्रॉपर्टी भी होती है. अगर यह false है, तो इसका मतलब है कि पेज को बैक/फ़ॉरवर्ड कैश मेमोरी में सेव नहीं किया जाएगा. हालांकि, 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 है, तो pagehide इवेंट के तुरंत बाद freeze इवेंट ट्रिगर होता है. हालांकि, इसका मतलब सिर्फ़ यह है कि ब्राउज़र पेज को कैश मेमोरी में सेव करने का इरादा रखता है. हालांकि, ऐसा हो सकता है कि उसे अब भी कई वजहों से इसे खारिज करना पड़े. इन वजहों के बारे में बाद में बताया गया है.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 से वापस लाने के बजाय फिर से लोड करने पर, वे ऐसा नहीं कर पाएंगे. इस स्थिति की जांच करना ज़रूरी है. सबसे अच्छा तरीका है कि आप A/B टेस्ट करें.

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

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

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

सुरक्षा के लिए जोखिम भरा होने के साथ-साथ, नॉन-नल window.opener रेफ़रंस वाले पेज को bfcache में सुरक्षित तरीके से नहीं रखा जा सकता. ऐसा इसलिए, क्योंकि इससे उस पेज को ऐक्सेस करने की कोशिश करने वाले किसी भी पेज को नुकसान पहुंच सकता है.

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

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

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

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

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

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

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

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

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

यहां दिए गए उदाहरण में बताया गया है कि IndexedDB का इस्तेमाल करने वाले पेजों के लिए, bfcache की सुविधा कैसे चालू की जाती है. इसके लिए, 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());

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

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

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

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

अगर टेस्ट पूरा हो जाता है, तो पैनल में "Restored from back-forward cache" रिपोर्ट दिखती है.

DevTools यह रिपोर्ट करता है कि किसी पेज को bfcache से वापस लाया गया है
ऐसे पेज का उदाहरण जिसे वापस लाया जा चुका है.

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

DevTools, बैक-फ़ॉरवर्ड कैश मेमोरी से किसी पेज को वापस लाने में हुई गड़बड़ी की जानकारी दे रहा है
बीएफ़कैश टेस्ट फ़ेल हो गया है. हालांकि, इसमें कार्रवाई करने लायक नतीजे मिले हैं.

इस उदाहरण में, unload इवेंट लिसनर का इस्तेमाल करने की वजह से, पेज पर बैक-फ़ॉरवर्ड कैश मेमोरी की सुविधा उपलब्ध नहीं है. unload से pagehide पर स्विच करके, इस समस्या को ठीक किया जा सकता है:

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

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

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

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

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

अगर आपको पेजव्यू की संख्या में 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 हिट रेशियो मेज़र करना

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

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

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

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

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

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

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

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

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

Core Web Vitals पर असर

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

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

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

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

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