वापरकर्ते ब्राउझरमधील इतर कोणत्याही कंट्रोलपेक्षा 'बॅक' (back) बटण जास्त वेळा दाबतात. त्यांना मागील स्क्रीन लगेच आणि त्यांनी जिथे सोडले होते अगदी त्याच ठिकाणी दिसावी अशी अपेक्षा असते. आधुनिक ब्राउझर 'back/forward cache' किंवा bfcache द्वारे ही अपेक्षा पूर्ण करतात. जेव्हा तुम्ही एखादे पेज सोडून दुसऱ्या पेजवर जाता, तेव्हा ब्राउझर ते पेज नष्ट करण्याऐवजी मेमरीमध्ये गोठवून (freeze) ठेवतो. जेव्हा तुम्ही परत येता, तेव्हा तो त्याचा स्नॅपशॉट (snapshot) पुन्हा कार्यान्वित करतो. ब्राउझर HTML पार्स करणे, JavaScript पुन्हा कार्यान्वित करणे आणि लेआउटची पुनर्गणना करणे या गोष्टी टाळतो. यामुळे प्रक्रिया अत्यंत वेगवान वाटते कारण पेज कधीच पूर्णपणे बंद झाले नव्हते.
bfcache प्रत्यक्षात काय करते
सामान्य पेज लोड करणे खर्चिक असते. ब्राउझरला रिसोर्सेस मिळवणे, HTML टोकनाइझ करणे, DOM तयार करणे, स्क्रिप्ट्स चालवणे, स्टाइल्स रिझॉल्व्ह करणे, लेआउट करणे, पिक्सेल पेंट करणे आणि लेयर्स कंपोझ करणे आवश्यक असते. bfcache पेजला RAM मध्ये गोठलेल्या स्थितीत जिवंत ठेवून यातील जवळजवळ सर्व गोष्टी टाळते. हे डिस्क कॅशे (disk cache) नाही. युजर पुढचे पेज वाचत असताना, रेंडर केलेले पेज, ज्यामध्ये JavaScript heap, स्क्रोल पोझिशन आणि फॉर्म स्टेटचा समावेश असतो, ते मेमरीमध्ये असते. जेव्हा युजर 'बॅक' क्लिक करतो, तेव्हा ब्राउझर तो स्नॅपशॉट पुन्हा सक्रिय (thaw) करतो आणि pageshow इव्हेंट फायर करतो. नेटवर्कचा वापर न करता किंवा शून्यापासून लेआउट पुन्हा न करता पेज पुन्हा सुरू होते. संथ डिव्हाइसेस किंवा अस्थिर कनेक्शन असलेल्या युजर्ससाठी, bfcache रिस्टोर आणि नवीन लोड यामधील फरक शेकडो मिलीसेकंद किंवा त्यापेक्षा जास्त असू शकतो.
काय यामुळे अडथळा आणते
bfcache नेमके काय अडवतो हे शोधण्यासाठी एका डेव्हलपरने अलीकडेच एक प्रयोग केला. त्यांनी सहा साधी पेजेस तयार केली, ज्यामध्ये प्रत्येक पेजवर एका संशयित अडथळ्याची (blocker) चाचणी घेतली, त्यानंतर ते पेज सोडून दुसऱ्या पेजवर गेले आणि 'बॅक' बटण दाबले. याचे निकाल स्पष्ट होते.
कोणतेही असामान्य हेडर्स किंवा स्क्रिप्ट्स नसलेले एक बेसलाइन पेज यशस्वीरित्या रिस्टोर झाले. beforeunload लिसनर असलेले पेज देखील कोणत्याही अडचणीशिवाय रिस्टोर झाले. आश्चर्याची गोष्ट म्हणजे, Cache-Control: no-store सह सर्व्ह केलेले पेज देखील bfcache मध्ये गेले, जे जुन्या मार्गदर्शक तत्त्वांच्या विरुद्ध होते. अगदी एक लाईव्ह ब्लॉग आर्टिकल देखील, जे गोठवण्यासाठी खूप डायनॅमिक वाटू शकते, यशस्वीरित्या रिस्टोर झाले.
दोन पेजेस अयशस्वी ठरली. unload इव्हेंट लिसनर असलेले पेज रिस्टोर होऊ शकले नाही. ओपन WebSocket कनेक्शन असलेले पेज देखील ब्लॉक झाले. हे दोन अपयश अशा सापळ्यांकडे (traps) निर्देश करतात जे दररोज प्रत्यक्ष प्रोडक्शन साइट्सना अडकवतात.
unload इव्हेंटचा सापळा
unload इव्हेंटचा वापर दीर्घकाळापासून शेवटच्या क्षणी क्लिनअप (cleanup) करण्यासाठी सिग्नल म्हणून केला जात आहे. डेव्हलपर्स याचा वापर ॲनालिटिक्स बीकन्स फ्लश करण्यासाठी, टाइमर्स थांबवण्यासाठी किंवा तात्पुरती स्टेट (temporary state) पुसून टाकण्यासाठी करतात. समस्या अशी आहे की, bfcache ही कल्पना आहे की पेज पुन्हा जिवंत होऊ शकते. जर ब्राउझरला unload लिसनर दिसले, तर त्याला असे वाटते की पेज पूर्णपणे नष्ट होण्याची अपेक्षा करत आहे आणि तो त्याला गोठण्यास नकार देतो. जोडलेले फंक्शन रिकामे असले तरीही फरक पडत नाही. लिसनरची केवळ उपस्थितीच प्रत्येक आधुनिक ब्राउझरमध्ये कॅशिंगला रोखण्यासाठी पुरेशी असते.
याचा पर्याय pagehide आहे. जेव्हा पेज bfcache साठी गोठवले जात असते आणि जेव्हा ते खरोखरच काढून टाकले जात असते, तेव्हा दोन्ही वेळी हा इव्हेंट फायर होतो. जर तुम्हाला या दोन्हीमधील फरक ओळखायचा असेल, तर जेव्हा पेज bfcache कडे जात असते तेव्हा event.persisted प्रॉपर्टी true असते. तथापि, बहुतेक क्लिनअप कामांसाठी pagehide दोन्ही मार्ग हाताळते. क्लिनअप लॉजिकचा प्रत्येक भाग unload मधून काढून pagehide मध्ये हलवा. त्यानंतर, थर्ड-पार्टी ॲनालिटिक्स स्निपेट्स किंवा जुन्या प्लगइन्समध्ये असलेले unload लिसनर्स देखील पूर्णपणे काढून टाका.
ॲक्टिव्ह कनेक्शनचे सापळे
एक ओपन नेटवर्क किंवा स्टोरेज कनेक्शन हे सूचित करते की तुमचे पेज अजूनही प्रत्यक्ष काम करत आहे. नेव्हिगेशनच्या वेळी ब्राउझर ॲक्टिव्ह रिसोर्सेसची यादी तपासतो. जर त्याला एखादे ओपन WebSocket, ॲक्टिव्ह WebRTC पीअर कनेक्शन किंवा प्रलंबित IndexedDB कनेक्शन आढळले, तर तो गोठण्याची प्रक्रिया थांबवतो आणि पेज सामान्यपणे बंद करतो. जोपर्यंत डेटा (bytes) प्रवाहित होत असू शकतो, तोपर्यंत स्नॅपशॉटवर विश्वास ठेवता येत नाही.
तुम्ही हे रिसोर्सेस pagehide लिसनरच्या आत बंद केले पाहिजेत. तुमच्या WebSocket ची close मेथड कॉल करा. WebRTC पीअर कनेक्शन्स बंद करा. कोणतेही प्रलंबित IndexedDB ट्रान्झॅक्शन्स अबॉर्ट (abort) किंवा कमिट (commit) करा. जर युजर परत आल्यावर तुमच्या ॲपला त्या चॅनेलची गरज असेल, तर त्यांना pageshow च्या आत पुन्हा उघडा. ही close-on-pagehide, restore-on-pageshow पद्धत कार्यक्षमता न गमावता पेजला त्वरित 'बॅक' नेव्हिगेशनसाठी पात्र ठेवते.
no-store चा धक्का
अनेक वर्षांपासून, Cache-Control: no-store मुळे bfcache रोखले जाते असे मानले जात होते. Chrome ने २०२५ मध्ये हे वर्तन बदलले आहे. आता no-store सह सर्व्ह केलेले पेज bfcache मध्ये जाऊ शकते. जर ऑथेंटिकेशन स्टेट्स किंवा कुकीज अशा प्रकारे बदलल्या ज्यामुळे सेव्ह केलेली स्टेट अवैध ठरते, तरच ब्राउझर नंतर तो गोठवलेला स्नॅपशॉट काढून टाकतो. जर तुम्ही no-store चा वापर
