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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

bfcache और iframe

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

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

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

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

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

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

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

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

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

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

देखें कि कोई पेज कब बीएफ़कैश डाल रहा है

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

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, Web Lock, WebSockets) तो यह समस्या हो सकती है, क्योंकि इन टास्क को रोकने से हो सकता है कि दूसरे टैब का कोड न चले.

इस वजह से, कुछ ब्राउज़र इन स्थितियों में किसी पेज को 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', ...);

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

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

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

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

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

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

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