बैक/फ़ॉरवर्ड कैश मेमोरी (या bfcache) एक ब्राउज़र ऑप्टिमाइज़ेशन है जो इंस्टैंट को चालू करता है पीछे और आगे के नेविगेशन पर क्लिक करें. यह ब्राउज़िंग अनुभव को काफ़ी बेहतर बनाता है, खासकर धीमे नेटवर्क या डिवाइस वाले उपयोगकर्ताओं के लिए.
वेब डेवलपर के तौर पर, यह समझना ज़रूरी है कि bfcache के लिए अपने पेजों को ऑप्टिमाइज़ कैसे किया जाए, ताकि आपके उपयोगकर्ताओं को इसका फ़ायदा मिल सके.
ब्राउज़र के साथ काम करना
bfcache का इस्तेमाल Firefox और Safari, दोनों के लिए कई सालों से किया जा रहा है. यह सुविधा डेस्कटॉप और मोबाइल, दोनों पर काम करती है.
वर्शन 86 से, Chrome ने कुछ उपयोगकर्ताओं के लिए, Android पर क्रॉस-साइट नेविगेशन के लिए बैक-कैश मेमोरी की सुविधा चालू कर दी है. इसके बाद वाली रिलीज़ में, अतिरिक्त सहायता धीरे-धीरे रोल आउट की गई. वर्शन 96 और इसके बाद के वर्शन में, डेस्कटॉप और मोबाइल पर सभी Chrome उपयोगकर्ताओं के लिए bfcache चालू है.
बैक-कैश मेमोरी की बुनियादी बातें
bfcache एक इन-मेमोरी कैश मेमोरी है जो उपयोगकर्ता के नेविगेट किए जाने के दौरान पेज का पूरा स्नैपशॉट (जिसमें JavaScript हीप भी शामिल है) सेव करती है. अगर उपयोगकर्ता इस पूरे पेज की मेमोरी में सेव होता है, तो उपयोगकर्ता को वापस लौटने का फ़ैसला लेने पर ब्राउज़र उसे तुरंत पहले जैसा कर सकता है.
ऐसा कितनी बार हुआ है कि आपने किसी वेबसाइट पर जाने के बाद, किसी दूसरे पेज पर जाने के लिए दिए गए लिंक पर क्लिक किया. ऐसा करने के बाद, आपको पता चला कि आपकी पसंद के मुताबिक पेज नहीं मिला और फिर 'वापस जाएं' बटन पर क्लिक करें? इस समय, bfcache का इस्तेमाल करने से यह काफ़ी हद तक अलग हो सकता है कि पिछला पेज कितनी तेज़ी से लोड होता है:
bfcache चालू नहीं होने पर | पिछले पेज को लोड करने के लिए एक नया अनुरोध किया जाता है. यह अनुरोध इस बात पर निर्भर करता है कि पेज पर दोबारा विज़िट करने के लिए उसे कितनी अच्छी तरह से ऑप्टिमाइज़ किया गया है. इसके बाद, हो सकता है कि ब्राउज़र को अभी-अभी डाउनलोड किए गए संसाधनों को फिर से डाउनलोड करना पड़े, उन्हें दोबारा पार्स करना पड़े, और फिर से लागू करना पड़े. |
bfcache चालू के साथ | पिछले पेज को लोड करना वाकई तुरंत होता है, क्योंकि पूरे पेज को मेमोरी से वापस लाया जा सकता है. इसके लिए, किसी नेटवर्क पर जाने की भी ज़रूरत नहीं पड़ती. |
bfcache का यह वीडियो देखें और समझें कि यह नेविगेशन में कितनी तेज़ी ला सकता है:
इस वीडियो में, bfcache वाला उदाहरण बिना नीति वाले उदाहरण के मुकाबले काफ़ी तेज़ है.
bfcache न केवल नेविगेशन की गति को बढ़ाता है, बल्कि यह डेटा उपयोग को भी कम करता है, क्योंकि संसाधनों को पुनः डाउनलोड करने की आवश्यकता नहीं होती.
Chrome के इस्तेमाल से जुड़े डेटा से पता चलता है कि डेस्कटॉप पर 10 में से 1 नेविगेशन और मोबाइल पर पांच में से एक नेविगेशन, पीछे या आगे की ओर हो रहा है. bfcache चालू होने से ब्राउज़र के डेटा के ट्रांसफ़र होने और हर दिन अरबों वेब पेजों के लोड होने में लगने वाले समय को खत्म करने में मदद मिल सकती है!
"कैश मेमोरी में सेव" कैसे होती है काम करता है
"कैश मेमोरी" bfcache के लिए इस्तेमाल किया जाने वाला कोड HTTP कैश से अलग होता है, जो दोहराए जाने वाले नेविगेशन की रफ़्तार बढ़ाने में अपनी भूमिका निभाता है. bfcache, मेमोरी में पूरे पेज का स्नैपशॉट है जिसमें JavaScript हीप भी शामिल है. हालांकि, एचटीटीपी कैश में सिर्फ़ पहले किए गए अनुरोधों के रिस्पॉन्स होते हैं. ऐसा बहुत कम होता है कि एचटीटीपी कैश मेमोरी से किसी पेज को लोड करने के लिए सभी अनुरोध पूरे किए जाएं. इसलिए, बीएफ़कैश मेमोरी का इस्तेमाल करके बार-बार आने वाले लोगों की विज़िट, सबसे अच्छी तरह ऑप्टिमाइज़ किए गए नॉन-बीएफ़एस कैश मेमोरी वाले नेविगेशन से भी ज़्यादा तेज़ होती है.
हालांकि, मेमोरी में किसी पेज का स्नैपशॉट बनाने के दौरान, प्रोसेस किए जा रहे कोड को सबसे सही तरीके से सुरक्षित रखने के मामले में कुछ दिक्कतें आती हैं. उदाहरण के लिए, अगर पेज बैक-कैश मेमोरी में सेव है, तो टाइम आउट होने पर setTimeout()
कॉल को कैसे मैनेज किया जाएगा?
इसका जवाब है कि ब्राउज़र बीएफ़कैश में सेव किए गए पेजों के लिए, उन टाइमर को रोक देता है या उनका समाधान नहीं करता है जिन्हें अभी तक पूरा नहीं किया गया है. इसमें JavaScript की टास्क सूची में मौजूद करीब-करीब सभी टास्क को प्रोसेस करना भी शामिल है. इसके अलावा, अगर पेज को बीएफ़कैश मेमोरी से वापस लाया जाता है, तो फिर से टास्क को प्रोसेस करना भी फिर से शुरू किया जा सकता है.
कुछ मामलों में, जैसे कि टाइम आउट और प्रॉमिसेस जैसे मामलों में, यह काफ़ी कम जोखिम होता है. हालांकि, अन्य मामलों में इसकी वजह से भ्रम की स्थिति पैदा हो सकती है या व्यवहार उम्मीद के मुताबिक नहीं हो सकता. उदाहरण के लिए, अगर ब्राउज़र किसी ऐसे टास्क को रोक देता है जो IndexedDB के हिस्से के तौर पर ज़रूरी है लेन-देन में शामिल है, तो इससे एक ही ऑरिजिन के दूसरे खुले टैब पर असर पड़ सकता है, क्योंकि एक ही IndexedDB डेटाबेस को कई टैब से एक साथ ऐक्सेस किया जा सकता है. इस वजह से ब्राउज़र आम तौर पर, IndexedDB ट्रांज़ैक्शन के बीच में या ऐसे एपीआई इस्तेमाल करते समय पेजों को कैश मेमोरी में सेव करने की कोशिश नहीं करेंगे जो दूसरे पेजों पर असर डाल सकते हैं.
एपीआई के अलग-अलग इस्तेमाल से पेज की बैक-कैश मेमोरी में सेव होने की शर्तों पर क्या असर पड़ता है, इस बारे में ज़्यादा जानने के लिए, बीएफ़कैश मेमोरी में डेटा सेव करने के लिए अपने पेजों को ऑप्टिमाइज़ करना लेख पढ़ें.
bfcache और iframe
अगर किसी पेज पर एम्बेड किए गए iframe हैं, तो iframes में एम्बेड नहीं किया जा सकता. उदाहरण के लिए, अगर iframe में मौजूद किसी अन्य पेज पर जाने के बाद वापस आता है, तो ब्राउज़र "वापस जाएं" पर जाएगा मुख्य फ़्रेम के बजाय iframe में सेट करें, लेकिन iframe में वापस मौजूद नेविगेशन, bfcache का इस्तेमाल नहीं करेगा.
अगर एम्बेड किया गया कोई iframe, इसे ब्लॉक करने वाले एपीआई का इस्तेमाल करता है, तो मुख्य फ़्रेम को bfcache का इस्तेमाल करने से भी रोका जा सकता है. इससे बचने के लिए, मुख्य फ़्रेम पर अनुमतियों की नीति का इस्तेमाल किया जा सकता है. इसके अलावा, sandbox
एट्रिब्यूट का इस्तेमाल करके भी ऐसा किया जा सकता है.
bfcache और सिंगल पेज ऐप्लिकेशन (SPA)
bfcache, ब्राउज़र से मैनेज किए जाने वाले नेविगेशन के साथ काम करता है. इसलिए, यह "सॉफ़्ट नेविगेशन" के लिए काम नहीं करता एक पेज के ऐप्लिकेशन (एसपीए) में. हालांकि, शुरुआत से ही उस ऐप्लिकेशन को पूरी तरह से शुरू करने के बजाय, SPA पर वापस जाने पर bfcache से मदद मिल सकती है.
bfcache निगरानी करने के लिए API
हालांकि, bfcache एक ऐसा ऑप्टिमाइज़ेशन है जिसे ब्राउज़र अपने-आप करते हैं, फिर भी डेवलपर के लिए यह जानना ज़रूरी है कि ऐसा कब हो रहा है. इससे, वे अपने पेजों को ऑप्टिमाइज़ कर सकते हैं और उस हिसाब से, किसी भी मेट्रिक या परफ़ॉर्मेंस मेज़रमेंट में बदलाव कर सकते हैं.
bfcache देखने के लिए इस्तेमाल किए जाने वाले मुख्य इवेंट, पेज ट्रांज़िशन इवेंट pageshow
और pagehide
हैं. ये ज़्यादातर ब्राउज़र पर काम करते हैं.
नए पेज लाइफ़साइकल इवेंट—freeze
और resume
—भी उस समय भेजे जाते हैं जब पेज, bfcache में जाते या छोड़े जाते हैं. साथ ही, कुछ दूसरी स्थितियों में भी भेजा जाता है. उदाहरण के लिए, जब सीपीयू का इस्तेमाल कम करने के लिए, बैकग्राउंड टैब फ़्रीज़ किया जाता है. ये इवेंट, सिर्फ़ Chromium कोड वाले ब्राउज़र में काम करते हैं.
देखें कि किसी पेज को बैक-कैश मेमोरी से कब वापस लाया गया है
load
इवेंट के ठीक बाद, जब पेज लोड हो रहा होता है और पेज को बैक-कैश मेमोरी से वापस लाया जाता है, तब pageshow
इवेंट ट्रिगर होता है. pageshow
इवेंट में persisted
प्रॉपर्टी मौजूद है. अगर पेज को bfcache से और false
से वापस लाया गया है, तो यह true
है. सामान्य पेज लोड और 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.');
}
});
पेज लाइफ़साइकल एपीआई के साथ काम करने वाले ब्राउज़र में resume
इवेंट तब ट्रिगर होता है, जब पेजों को बैक-कैश मेमोरी से वापस लाया जाता है (pageshow
इवेंट के तुरंत पहले) और कोई उपयोगकर्ता फ़्रीज़ किए गए बैकग्राउंड टैब पर फिर से जाता है. किसी पेज को फ़्रीज़ होने के बाद उसकी स्थिति अपडेट करने के लिए, resume
इवेंट का इस्तेमाल करें. हालांकि, अगर आपको अपनी साइट के बीएफ़कैश हिट रेट को मेज़र करना है, तो आपको pageshow
इवेंट का इस्तेमाल करना होगा. कुछ मामलों में, आपको दोनों का इस्तेमाल करना पड़ सकता है.
bfcache मेज़रमेंट के सबसे सही तरीकों के बारे में जानकारी के लिए, bfcache मेज़र करने के आंकड़ों और परफ़ॉर्मेंस को मेज़र करने का तरीका देखें.
देखें कि कोई पेज कब बीएफ़कैश डाल रहा है
pagehide
इवेंट तब ट्रिगर होता है, जब पेज अनलोड हो जाता है या जब ब्राउज़र उसे बैक-कैश मेमोरी में डालने की कोशिश करता है.
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
इवेंट के तुरंत बाद फ़ायर होता है. हालांकि, इसका मतलब है कि ब्राउज़र पेज को कैश मेमोरी में सेव करने का दावा करता है. कई वजहों से इसे अब भी खारिज किया जा सकता है. इन वजहों के बारे में बाद में बताया गया है.
बैक-कैश मेमोरी के लिए अपने पेजों को ऑप्टिमाइज़ करना
सभी पेज, बैक-कैश मेमोरी में सेव नहीं होते. साथ ही, अगर कोई पेज वहां सेव हो भी जाता है, तो वह लंबे समय तक वहां नहीं रहता. यह ज़रूरी है कि डेवलपर यह समझें कि किन वजहों से पेज, कैश मेमोरी में सेव होने की दर ज़्यादा से ज़्यादा बढ़ा सकते हैं. इसके लिए, यह ज़रूरी है कि उन पेजों को बीएफ़कैश मेमोरी के लिए मंज़ूरी (और ज़रूरी शर्तें पूरी न करने वाला) माना जाए.
नीचे दिए सेक्शन में, ब्राउज़र के कैश मेमोरी में सेव होने की संभावना को बढ़ाने के सबसे सही तरीकों के बारे में बताया गया है.
unload
इवेंट का कभी भी इस्तेमाल न करें
सभी ब्राउज़र में bfcache के लिए ऑप्टिमाइज़ करने का सबसे ज़रूरी तरीका यह है कि unload
इवेंट का इस्तेमाल कभी न किया जाए. हमेशा!
unload
इवेंट, ब्राउज़र के लिए समस्याजनक होता है. इसकी वजह यह है कि यह बीएफ़कैश मेमोरी से पहले की तरह काम करता है. साथ ही, इंटरनेट पर कई पेज इस अनुमान के आधार पर ऑपरेट करते हैं कि unload
इवेंट के ट्रिगर होने के बाद भी कोई पेज मौजूद नहीं रहेगा. यह एक चुनौती है, क्योंकि उनमें से कई पेज भी यह मानकर बनाए गए थे कि unload
इवेंट किसी भी बार उपयोगकर्ता के नेविगेट करने पर सक्रिय हो जाएगा, जो अब सही नहीं है (और लंबे समय से सही नहीं है).
इसलिए, ब्राउज़र को किसी दुविधा का सामना करना पड़ता है, इसलिए उन्हें एक ऐसी चीज़ चुननी होती है जो उपयोगकर्ता अनुभव को बेहतर बना सके—लेकिन उनके पेज के टूट जाने का जोखिम भी हो सकता है.
डेस्कटॉप पर, Chrome और Firefox ने unload
लिसनर जोड़ने पर, पेजों को bfकैश मेमोरी में सेव करने की अनुमति नहीं दी है. यह कम जोखिम भरा है, लेकिन कई पेजों को काम करना बंद कर देता है. Safari, unload
इवेंट लिसनर की मदद से कुछ पेजों को कैश मेमोरी में सेव करने की कोशिश करेगा. हालांकि, अगर कोई उपयोगकर्ता किसी दूसरी साइट पर जा रहा है, तो संभावित गड़बड़ी को कम करने के लिए वह unload
इवेंट को नहीं चलाएगा. इस वजह से, इवेंट का भरोसा नहीं हो पाएगा.
मोबाइल पर, Chrome और Safari, unload
इवेंट लिसनर की मदद से पेजों को कैश मेमोरी में सेव करने की कोशिश करेंगे. ऐसा इसलिए, क्योंकि unload
इवेंट, मोबाइल पर हमेशा से पूरी तरह से भरोसेमंद नहीं रहा है. इसलिए, Chrome के हैक होने का जोखिम कम होता है. Firefox ऐसे पेजों के साथ करता है जो unload
का इस्तेमाल bfcache के लिए नहीं करते हैं. हालांकि, iOS के लिए यह ज़रूरी है कि सभी ब्राउज़र में WebKit रेंडरिंग इंजन इस्तेमाल किया जाए. इसलिए, यह Safari की तरह काम करता है.
unload
इवेंट के बजाय, pagehide
इवेंट का इस्तेमाल करें. pagehide
इवेंट उन सभी मामलों में फ़ायर होता है जहां unload
इवेंट ट्रिगर होता है. साथ ही, यह तब भी ट्रिगर होता है, जब किसी पेज को बैक-कैश मेमोरी में रखा जाता है.
असल में, Lighthouse में एक no-unload-listeners
ऑडिट है. यह डेवलपर को तब चेतावनी देगा, जब उनके पेजों पर मौजूद कोई भी JavaScript, unload
इवेंट लिसनर को जोड़ेगा. इनमें तीसरे पक्ष की लाइब्रेरी का JavaScript भी शामिल है.
इसके भरोसेमंद नहीं होने और bfcache की सुविधा की वजह से Chrome की परफ़ॉर्मेंस पर असर पड़ सकता है. इसलिए, Chrome unload
इवेंट को बंद करने की कोशिश कर रहा है.
किसी पेज पर अनलोड हैंडलर का इस्तेमाल करने से रोकने के लिए, अनुमति से जुड़ी नीति का इस्तेमाल करें
जो साइटें unload
इवेंट हैंडलर का इस्तेमाल नहीं करती हैं वे यह पक्का कर सकती हैं कि उन्हें अनुमतियों की नीति का इस्तेमाल करके नहीं जोड़ा गया है.
Permission-Policy: unload=()
यह तीसरे पक्षों या एक्सटेंशन को अनलोड हैंडलर जोड़कर साइट को धीमा करने से भी रोकता है और साइट को बीएफ़कैश के लिए मंज़ूरी नहीं देता.
सिर्फ़ शर्तों के साथ 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 से वापस लाया जाता है, तो उसे मेमोरी से वापस लाया जाता है, न कि एचटीटीपी कैश से. इस वजह से, Cache-Control: no-cache
या Cache-Control: max-age=0
जैसे निर्देशों पर ध्यान नहीं दिया जाता है और उपयोगकर्ता को कॉन्टेंट दिखाए जाने से पहले, दोबारा पुष्टि नहीं की जाती है.
हालांकि, इससे उपयोगकर्ता को बेहतर अनुभव मिल सकता है. हालांकि, bfcache रिस्टोर तुरंत प्रोसेस करता है और पेज बहुत लंबे समय तक bfcache में नहीं रहते हैं. इसलिए, हो सकता है कि आपका कॉन्टेंट पुराना हो. हालांकि, अगर आपका कॉन्टेंट हर मिनट में बदलता है, तो 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 टेस्ट के साथ टेस्ट करना ज़रूरी है.
जो साइटें बैक-कैश मेमोरी में सेव करने की सुविधा को चालू करने के बाद विज्ञापनों को रीफ़्रेश करना चाहती हैं वे event.persisted
के true
होने पर, pageshow
इवेंट में विज्ञापनों को रीफ़्रेश करती हैं. इससे, पेज की परफ़ॉर्मेंस पर कोई असर नहीं पड़ता. अपनी विज्ञापन कंपनी से संपर्क करें, लेकिन Google पब्लिशिंग टैग के साथ ऐसा करने के तरीके के बारे में यहां एक उदाहरण दिया गया है.
window.opener
रेफ़रंस से बचें
पुराने ब्राउज़र में, अगर window.open()
का इस्तेमाल करके target=_blank
वाले लिंक से कोई पेज खोला जाता है और उसमें rel="noopener"
शामिल नहीं किया जाता, तो खुलने वाले पेज में, खुले हुए पेज के विंडो ऑब्जेक्ट की जानकारी होती है.
सुरक्षा से जुड़ा जोखिम होने के अलावा, बिना शून्य window.opener
रेफ़रंस वाले पेज को सुरक्षित तरीके से बीएफ़कैश में नहीं रखा जा सकता, क्योंकि इससे ऐक्सेस करने की कोशिश करने वाले किसी भी पेज में गड़बड़ी हो सकती है.
इसलिए, window.opener
पहचान फ़ाइल बनाने से बचना बेहतर होगा. ऐसा करने के लिए, जब भी मुमकिन हो rel="noopener"
का इस्तेमाल करें (ध्यान दें, अब यह सभी मॉडर्न ब्राउज़र में डिफ़ॉल्ट तौर पर सेट हो जाता है). अगर आपकी साइट को किसी विंडो को खोलने और उसे window.postMessage()
की मदद से कंट्रोल करने या सीधे विंडो ऑब्जेक्ट का रेफ़रंस देने की ज़रूरत है, तो खुली हुई विंडो और ओपनर में से किसी एक को बीएफ़कैश नहीं किया जा सकेगा.
उपयोगकर्ता के ब्राउज़र छोड़ने से पहले, खुले हुए कनेक्शन बंद करें
जैसा कि पहले ही बताया जा चुका है, जब किसी पेज को कैश मेमोरी में सेव किया जाता है, तब यह शेड्यूल किए गए सभी JavaScript टास्क रोक देता है. साथ ही, पेज को कैश मेमोरी से बाहर निकालने के बाद, यह टास्क फिर से शुरू हो जाता है.
अगर शेड्यूल किए गए ये JavaScript टास्क सिर्फ़ DOM API को ऐक्सेस कर रहे हैं या किसी दूसरे एपीआई को सिर्फ़ मौजूदा पेज तक ऐक्सेस कर रहे हैं, तो उपयोगकर्ता को पेज नहीं दिखने पर इन टास्क को रोक दें. इससे कोई समस्या नहीं होगी.
हालांकि, अगर ये टास्क ऐसे एपीआई से कनेक्ट किए गए हैं जिन्हें उसी ऑरिजिन के अन्य पेजों से भी ऐक्सेस किया जा सकता है (उदाहरण के लिए: IndexedDB, Web Lock, WebSockets) तो यह समस्या हो सकती है, क्योंकि इन टास्क को रोकने से, हो सकता है कि दूसरे टैब का कोड न चले.
इस वजह से, कुछ ब्राउज़र इन स्थितियों में पेज को बैक-कैश मेमोरी में सेव करने की कोशिश नहीं करेंगे:
- ओपन IndexedDB कनेक्शन वाले पेज
- जिन पेजों पर fetch() या XMLHttpRequest को लागू किया जा रहा है
- ओपन WebSocket या WebRTC कनेक्शन वाले पेज
अगर आपके पेज में इनमें से किसी भी एपीआई का इस्तेमाल किया जा रहा है, तो हमारा सुझाव है कि 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 की मदद से आपके पेजों की जांच की जा सकती है. इससे यह पक्का किया जा सकता है कि पेजों को बैक-कैश मेमोरी के लिए ऑप्टिमाइज़ किया गया है. साथ ही, इस टूल से उन समस्याओं की पहचान भी की जा सकती है जिनकी वजह से पेज ज़रूरी शर्तें पूरी नहीं करते.
किसी पेज की जांच करने के लिए:
- Chrome में पेज पर जाएं.
- DevTools में ऐप्लिकेशन पर जाएं -> बैक-फ़ॉरवर्ड कैश मेमोरी.
- जांच करें बटन पर क्लिक करें. इसके बाद, DevTools किसी दूसरी जगह पर वापस जाने की कोशिश करता है ताकि यह तय किया जा सके कि पेज को bfcache से वापस लाया जा सकता है या नहीं.
![DevTools में बैक-फ़ॉरवर्ड कैश मेमोरी का पैनल](https://web.dev/static/articles/bfcache/image/back-forward-cache-panel-fc27405c6cd76.png?authuser=6&hl=hi)
जांच पूरी होने पर, पैनल "बैक-फ़ॉरवर्ड कैश मेमोरी से वापस लाया गया" रिपोर्ट करता है.
![DevTools की मदद से यह रिपोर्टिंग की जा रही है कि पेज को Bfcache से वापस लाया गया](https://web.dev/static/articles/bfcache/image/devtools-reporting-page-1dd392594f6b2.png?authuser=6&hl=hi)
अगर अनुरोध सफल नहीं होता है, तो पैनल इसकी वजह भी बताता है. अगर किसी वजह को डेवलपर के तौर पर ठीक किया जा सकता है, तो पैनल उसे कार्रवाई करने की सुविधा के तौर पर मार्क करता है.
![DevTools रिपोर्टिंग की प्रोसेस के दौरान, किसी पेज को बैक-कैश मेमोरी से वापस नहीं लाया जा सका](https://web.dev/static/articles/bfcache/image/devtools-reporting-failur-e962032a9c1e2.png?authuser=6&hl=hi)
इस उदाहरण में, unload
इवेंट लिसनर का इस्तेमाल करने पर, पेज को बैक अप कैश मेमोरी में सेव होने की अनुमति नहीं दी गई. unload
से pagehide
का इस्तेमाल करके, इस समस्या को ठीक किया जा सकता है:
window.addEventListener('pagehide', ...);
window.addEventListener('unload', ...);
लाइटहाउस 10.0 ने bfcache ऑडिट भी जोड़ा. यह इसी तरह का टेस्ट करता है. ज़्यादा जानकारी के लिए, bfcache ऑडिट के दस्तावेज़ देखें.
bfcache, आंकड़ों और परफ़ॉर्मेंस के मेज़रमेंट पर कैसे असर डालता है
अपनी साइट पर आने वाले लोगों की संख्या को मेज़र करने के लिए, किसी ऐनलिटिक्स टूल का इस्तेमाल करने पर, आपको पेज व्यू की कुल संख्या में कमी दिख सकती है. इसकी वजह यह है कि Chrome ज़्यादा उपयोगकर्ताओं के लिए, कैश मेमोरी में डेटा सेव करने की सुविधा चालू करता है.
ऐसा हो सकता है कि आपने पहले से ही ऐसे ब्राउज़र के पेज व्यू को कम रिपोर्ट किया हो जो बैक-कैश मेमोरी को लागू करते हैं. इसकी वजह यह है कि आंकड़ों से जुड़ी कई लोकप्रिय लाइब्रेरी, 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
API जोड़ा है, ताकि पेजों के लिए bfcache का इस्तेमाल न किए जाने की वजहों का पता चल सके. इससे डेवलपर, अपने बीएफ़कैश हिट रेट को बेहतर बना सकते हैं. Chrome टीम ने CrUX में नेविगेशन के टाइप भी जोड़े हैं. इसकी मदद से, कैश मेमोरी में सेव किए गए नेविगेशन की संख्या को देखा जा सकता है. भले ही, नेविगेशन की संख्या खुद मेज़र न की गई हो.
परफ़ॉर्मेंस मेज़रमेंट
bfcache, फ़ील्ड में इकट्ठा की गई परफ़ॉर्मेंस मेट्रिक पर भी बुरा असर डाल सकता है. खास तौर पर, उन मेट्रिक पर जो पेज लोड होने में लगने वाले समय का पता लगाती हैं.
कैश मेमोरी में सेव किए गए डेटा को नेविगेट करने की सुविधा की मदद से, नया पेज लोड होने के बजाय मौजूदा पेज को वापस लाया जाता है. इसलिए, bfकैश मेमोरी में सेव करने की सुविधा चालू होने पर, इकट्ठा किए गए पेज लोड की कुल संख्या कम हो जाएगी. हालांकि, अहम बात यह है कि जिस पेज लोड को bfcache रिस्टोर से बदला जा रहा है वह आपके डेटासेट में सबसे तेज़ी से लोड होने वाले पेज में से एक हो सकता है. ऐसा इसलिए होता है, क्योंकि परिभाषा के मुताबिक, पीछे और आगे जाने वाले नेविगेशन, बार-बार होने वाले विज़िट होते हैं. साथ ही, बार-बार होने वाले पेज लोड, आम तौर पर पहली बार आने वाले लोगों के पेज लोड होने की तुलना में ज़्यादा तेज़ होते हैं. ऐसा एचटीटीपी कैश मेमोरी में होने की वजह से होता है, जैसा कि पहले बताया गया है.
इसका नतीजा यह होता है कि आपके डेटासेट में तेज़ी से लोड होने वाले पेज कम हो जाते हैं. इस वजह से डिस्ट्रिब्यूशन धीमा हो सकता है. भले ही, लोगों को मिलने वाली परफ़ॉर्मेंस में सुधार हुआ हो!
इस समस्या से निपटने के कुछ तरीके हैं. इनमें से एक तरीका यह है कि पेज लोड की सभी मेट्रिक के बारे में नेविगेशन टाइप के साथ जानकारी दी जाए: navigate
, reload
, back_forward
या prerender
. इसकी मदद से, इन नेविगेशन टाइप में अपनी परफ़ॉर्मेंस पर नज़र रखी जा सकती है, भले ही कुल डिस्ट्रिब्यूशन में गिरावट आए. हमारा सुझाव है कि यह तरीका, उपयोगकर्ताओं पर आधारित पेज लोड की मेट्रिक, जैसे कि टाइम टू फ़र्स्ट बाइट (टीटीएफ़बी) के लिए इस्तेमाल न करें.
वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी जैसी उपयोगकर्ता पर आधारित मेट्रिक के लिए, एक बेहतर विकल्प यह है कि आप उपयोगकर्ता के अनुभव की ज़्यादा सटीक जानकारी दें.
वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी पर इसका असर
वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी, अलग-अलग डाइमेंशन के हिसाब से उपयोगकर्ता को वेब पेज का अनुभव दिखाती है. इन डाइमेंशन में लोड होने की स्पीड, इंटरैक्टिविटी, और विज़ुअल स्टेबिलिटी शामिल हैं. इसलिए, पूरा पेज लोड होने की तुलना में, साइट पर एक जगह से दूसरी जगह पर ज़्यादा तेज़ी से नेविगेट किया जा सकता है. इसलिए, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक से इस बात का आकलन करना ज़रूरी है. ऐसा इसलिए, क्योंकि किसी उपयोगकर्ता को इस बात की परवाह नहीं होती कि bfcache चालू है या नहीं. उसे बस इस बात की परवाह होती है कि नेविगेशन तेज़ था!
वेबसाइट की परफ़ॉर्मेंस की जानकारी देने वाली मेट्रिक जैसे कि Chrome के उपयोगकर्ता अनुभव की रिपोर्ट को इकट्ठा करने और रिपोर्ट करने वाले टूल, अपने डेटासेट में, कैश मेमोरी में सेव हुए डेटा को वापस लाने की जानकारी को अलग-अलग पेज विज़िट के तौर पर देखते हैं. हालांकि, bfcache रिस्टोर के बाद इन मेट्रिक को मेज़र करने के लिए वेब परफ़ॉर्मेंस एपीआई उपलब्ध नहीं हैं, लेकिन मौजूदा वेब एपीआई का इस्तेमाल करके उनकी वैल्यू का अनुमान लगाया जा सकता है:
- सबसे बड़े कॉन्टेंटफ़ुल पेंट (एलसीपी) के लिए,
pageshow
इवेंट के टाइमस्टैंप और पेंट किए गए अगले फ़्रेम के टाइमस्टैंप के बीच डेल्टा का इस्तेमाल करें. ऐसा इसलिए, क्योंकि फ़्रेम में मौजूद सभी एलिमेंट एक ही समय पर पेंट किए जाएंगे. बैक-कैश मेमोरी को रीस्टोर करने के मामले में, एलसीपी और एफ़सीपी एक जैसे होते हैं. - इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) के लिए, अपने मौजूदा परफ़ॉर्मेंस ऑब्ज़र्वर का इस्तेमाल करते रहें, लेकिन आईएनपी की मौजूदा वैल्यू को 0 पर रीसेट करें.
- कुल लेआउट शिफ़्ट (सीएलएस) के लिए, अपने मौजूदा परफ़ॉर्मेंस ऑब्ज़र्वर का इस्तेमाल करते रहें, लेकिन मौजूदा सीएलएस वैल्यू को 0 पर रीसेट करें.
bfcache हर मेट्रिक पर कैसे असर डालता है, इस बारे में ज़्यादा जानकारी के लिए, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाले मेट्रिक से जुड़े गाइड वाले पेज देखें. इन मेट्रिक के bfcache वर्शन लागू करने के खास उदाहरण के लिए, उन्हें वेब-वाइटल JS लाइब्रेरी में जोड़ने के लिए पीआर की नीति देखें.
वेब-वाइटल JavaScript लाइब्रेरी, रिपोर्ट की जाने वाली मेट्रिक में बीएफ़कैश मेमोरी को वापस लाने की सुविधा देती है.
अतिरिक्त संसाधन
- Firefox कैश मेमोरी (Firefox में bfcache)
- पेज की कैश मेमोरी (Safari में bfcache)
- बैक/फ़ॉरवर्ड कैश मेमोरी: वेब पर बिना अनुमति के सार्वजनिक व्यवहार (सभी ब्राउज़र में कैश मेमोरी में अंतर)
- bfकैश मेमोरी टेस्टर (जांचें कि अलग-अलग एपीआई और इवेंट, ब्राउज़र में bfcache पर कैसे असर डालते हैं)
- परफ़ॉर्मेंस गेम चेंजर: ब्राउज़र की बैक/फ़ॉरवर्ड कैश मेमोरी (Sashing Journal की केस स्टडी, जिसमें bfcache को चालू करके Core Web Vitals में किए गए सुधार दिखाए गए हैं)