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

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

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

वेबसाइट का अलग-अलग ब्राउज़र पर चलना

bfcache कई सालों से Firefox और Safari, दोनों में डेस्कटॉप और मोबाइल पर काम करता रहा है.

वर्शन 86 से, Chrome ने कुछ उपयोगकर्ताओं के लिए Android पर क्रॉस-साइट नेविगेशन के लिए, बैक-फ़ॉरवर्ड कैश मेमोरी की सुविधा को चालू किया है. इसके बाद की रिलीज़ में, अतिरिक्त सहायता धीरे-धीरे रोल आउट की गई. वर्शन 96 से, डेस्कटॉप और मोबाइल पर Chrome का इस्तेमाल करने वाले सभी लोगों के लिए बैक-फ़ॉरवर्ड कैश मेमोरी की सुविधा चालू है.

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

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

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

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

बैक-फ़ॉरवर्ड कैश मेमोरी की सुविधा का इस्तेमाल करके बनाए गए इस वीडियो को देखें. इससे आपको पता चलेगा कि इससे नेविगेशन में कितनी तेज़ी से बढ़ोतरी हो सकती है:

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

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

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

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

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

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

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

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

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

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

bfcache और iframes

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

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

Bfcache और सिंगल पेज ऐप्लिकेशन (SPA)

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

bfcache के लिए एपीआई

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

बैक-फ़ॉरवर्ड कैश मेमोरी की जांच करने के लिए, मुख्य इवेंट पेज ट्रांज़िशन इवेंट pageshow और pagehide हैं. ये इवेंट ज़्यादातर ब्राउज़र पर काम करते हैं.

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

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

जब पेज शुरू में लोड होता है और जब भी पेज bfcache से वापस लाया जाता है, तो pageshow इवेंट, load इवेंट के तुरंत बाद फ़ायर हो जाता है. pageshow इवेंट में persisted प्रॉपर्टी है. अगर पेज को bfcache से वापस लाया गया था, तो यह true होती है. अगर पेज को bfcache से वापस लाया गया था, तो वैल्यू false होती है. सामान्य पेज लोड और bfcache के तरीके को पहले जैसा करने की सुविधा में अंतर करने के लिए, 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 के आंकड़ों और परफ़ॉर्मेंस को मेज़र करने के सबसे सही तरीकों का तरीका देखें.

देखें कि कोई पेज bfcache में पड़ रहा है या नहीं

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

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

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

बैक-फ़ॉरवर्ड कैश मेमोरी के लिए, अपने पेजों को ऑप्टिमाइज़ करें

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

window.opener रेफ़रंस का इस्तेमाल करने से बचें

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

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

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

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

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

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

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

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

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

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

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

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req. => req.result.createObjectStore('keyval');
      req. => reject(req.error);
      req. => 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, आपके पेजों की जांच करने में मदद कर सकता है. इससे यह पक्का किया जा सकता है कि उन्हें बैक-फ़ॉरवर्ड कैश मेमोरी के लिए ऑप्टिमाइज़ किया गया है. साथ ही, Chrome DevTools की मदद से उन समस्याओं की पहचान की जा सकती है जो उन्हें Google Search के नतीजों में दिखने से रोक सकती हैं.

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

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

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

DevTools की मदद से यह बताया जा रहा है कि पेज को bfcache से वापस लाया गया
पेज को पहले जैसा किया गया.

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

DevTools रिपोर्टिंग से, पेज को 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 का इस्तेमाल नहीं कर रहे हैं. पेज लोड के लिए, नेविगेशन टाइप को मेज़र करके ऐसा किया जा सकता है:

// 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 का इस्तेमाल नहीं करेगी, तो इनमें ये शामिल हैं:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

जानकारी पाने के दूसरे तरीके