ब्राउज़र सहायता
- 68
- 79
- x
- x
आज-कल के मॉडर्न ब्राउज़र कभी-कभी पेजों को निलंबित कर देते हैं या सिस्टम के रिसॉर्स सीमित होने पर, उन्हें पूरी तरह से खारिज कर देते हैं. आने वाले समय में, ब्राउज़र ऐसा करना चाहते हैं, ताकि वे कम पावर और मेमोरी का इस्तेमाल करें. Page Lifecycle API से लाइफ़साइकल हुक मिलते हैं, ताकि आपके पेज उपयोगकर्ता अनुभव पर असर डाले बिना, ब्राउज़र की इन गतिविधियों को सुरक्षित तरीके से मैनेज कर सकें. एपीआई पर एक नज़र डालें और देखें कि आपको अपने ऐप्लिकेशन में इन सुविधाओं को लागू करना चाहिए या नहीं.
बैकग्राउंड
ऐप्लिकेशन लाइफ़साइकल एक मुख्य तरीका है, जिससे आधुनिक ऑपरेटिंग सिस्टम संसाधनों को मैनेज करते हैं. Android, iOS, और हाल ही के Windows वर्शन पर, ओएस की मदद से किसी भी समय ऐप्लिकेशन चालू किए जा सकते हैं. साथ ही, उन्हें बंद भी किया जा सकता है. इससे इन प्लैटफ़ॉर्म को संसाधनों को व्यवस्थित करने और उन्हें फिर से उपलब्ध कराने में मदद मिलती है. इससे लोगों को सबसे ज़्यादा फ़ायदा मिलता है.
वेब पर, हमेशा से ऐसी कोई लाइफ़साइकल नहीं होती है और ऐप्लिकेशन को हमेशा के लिए ज़िंदा रखा जा सकता है. बड़ी संख्या में वेब पेज चलने की वजह से, मेमोरी, सीपीयू, बैटरी, और नेटवर्क जैसे ज़रूरी सिस्टम संसाधनों की सदस्यता ले ली जा सकती है. इससे असली उपयोगकर्ताओं को खराब अनुभव मिलता है.
वेब प्लैटफ़ॉर्म पर लंबे समय से ऐसे इवेंट मौजूद हैं जो लाइफ़साइकल की स्थितियों से जुड़े रहते हैं, जैसे कि load
,
unload
, और
visibilitychange
— ये इवेंट सिर्फ़ डेवलपर को उपयोगकर्ता की शुरू की गई लाइफ़साइकल की स्थिति में हुए बदलावों के हिसाब से जवाब देने की अनुमति देते हैं. वेब के लिए कम क्षमता वाले डिवाइस पर सही तरीके से काम
करने के लिए (और सभी प्लैटफ़ॉर्म पर अपनी संसाधनों को बेहतर तरीके से इस्तेमाल करना)
के लिए, ब्राउज़र को सिस्टम के संसाधनों पर अपने-आप फिर से दावा करने और उन्हें फिर से असाइन
करने के तरीके की ज़रूरत होती है.
असल में, मौजूदा ब्राउज़र पहले से ही बैकग्राउंड में चल रहे टैब के पेजों के लिए, संसाधनों की बचत करने के लिए ज़रूरी कदम उठाते रहते हैं. ऐसे में, कई ब्राउज़र (खास तौर पर Chrome) इसी तरह के बहुत से काम करना चाहेंगे, ताकि संसाधनों की पूरी दुनिया में उनका इस्तेमाल कम किया जा सके.
समस्या यह है कि डेवलपर के पास इस तरह के सिस्टम की ओर से शुरू किए गए इंटरवेंशन के लिए तैयार होने का कोई तरीका नहीं है या उन्हें पता भी नहीं होता कि ये रुकावटें हो रही हैं. इसका मतलब है कि ब्राउज़र को ज़रूरत से ज़्यादा सावधानी बरतनी चाहिए या वेब पेज तोड़ने का जोखिम होना चाहिए.
Page Lifecycle API इस समस्या को हल करने की कोशिश करता है:
- वेब पर लाइफ़साइकल की स्थितियों के सिद्धांत को पेश किया जा रहा है और उसके लिए स्टैंडर्ड तय किया जा रहा है.
- सिस्टम की मदद से शुरू की गई नई स्थितियों के बारे में जानकारी. इनसे ब्राउज़र उन संसाधनों को सीमित कर पाते हैं जिनका इस्तेमाल, छिपे हुए या इनऐक्टिव टैब से किया जा सकता है.
- ऐसे नए एपीआई और इवेंट बनाना जो वेब डेवलपर को सिस्टम से शुरू की गई इन नई स्थितियों में होने वाले बदलावों के हिसाब से कार्रवाई करने की अनुमति दें.
यह समाधान ऐसा ऐप्लिकेशन है जिसके लिए वेब डेवलपर को ऐसे ऐप्लिकेशन बनाने की ज़रूरत होती है जो सिस्टम के इंटरवेंशन के हिसाब से सही हों. साथ ही, यह ब्राउज़र को सिस्टम के संसाधनों को ज़्यादा असरदार तरीके से ऑप्टिमाइज़ करने में मदद करता है. इससे सभी वेब उपयोगकर्ताओं को फ़ायदा मिलता है.
इस पोस्ट के अगले हिस्से में, पेज लाइफ़साइकल की नई सुविधाओं के बारे में बताया जाएगा. साथ ही, यह भी जाना जाएगा कि वेब प्लैटफ़ॉर्म की सभी मौजूदा स्थितियों और इवेंट से ये सुविधाएं कैसे जुड़ी हैं. इस डेटा में यह भी बताया जाएगा कि डेवलपर को किस तरह के काम हर राज्य में करने चाहिए और किस तरह नहीं करने चाहिए.
पेज लाइफ़साइकल की स्थितियों और इवेंट की खास जानकारी
पेज की सभी लाइफ़साइकल की स्थिति अलग-अलग और म्युचुअली एक्सक्लूसिव होती हैं. इसका मतलब है कि कोई पेज एक समय पर सिर्फ़ एक स्थिति में हो सकता है. किसी पेज की लाइफ़साइकल स्थिति में होने वाले ज़्यादातर बदलावों को आम तौर पर डीओएम इवेंट के ज़रिए देखा जाता है (अपवादों के लिए हर स्थिति के लिए डेवलपर के सुझाव देखें).
पेज लाइफ़साइकल की स्थितियों और उनके बीच ट्रांज़िशन का सिग्नल देने वाले इवेंट को समझाने का सबसे आसान तरीका, डायग्राम की मदद से है:
राज्य
यहां दी गई टेबल में हर राज्य के बारे में पूरी जानकारी दी गई है. इसमें उन संभावित स्थितियों की सूची भी होती है जो पहले और बाद के हो सकती हैं. साथ ही, इसमें उन इवेंट की सूची भी होती है जिनका इस्तेमाल डेवलपर, बदलावों पर नज़र रखने के लिए कर सकते हैं.
स्थिति | ब्यौरा |
---|---|
चालू |
अगर कोई पेज दिख रहा है और उसमें इनपुट फ़ोकस मौजूद है, तो वह चालू स्थिति में होता है.
संभावित पिछली स्थितियां: |
पैसिव |
अगर पेज दिख रहा है और उसमें इनपुट फ़ोकस मौजूद नहीं है, तो यह बंद स्थिति में होता है.
संभावित पिछली स्थितियां:
अगली स्थिति: |
छिपा हुआ |
अगर कोई पेज नहीं दिखता है, तो यह छिपा हुआ स्थिति में होता है. साथ ही, पेज को फ़्रीज़, खारिज या खत्म न किया गया हो.
संभावित पिछली स्थितियां:
आगे की संभावित स्थितियां: |
फ़्रोज़न |
फ़्रीज़ स्थिति में, ब्राउज़र, पेज की
टास्क सूची में,
फ़्रीज़ किए जा सकने वाले
टास्क के एक्ज़ीक्यूशन को तब तक के लिए निलंबित करता है, जब तक पेज के फ़्रीज़ नहीं हो जाते. इसका मतलब है कि JavaScript टाइमर और फ़ेच कॉलबैक जैसी चीज़ें नहीं चलती हैं. पहले से चल रहे
टास्क पूरे हो सकते हैं (खास तौर पर,
ब्राउज़र, सीपीयू/बैटरी/डेटा खर्च को बनाए रखने के लिए पेजों को फ़्रीज़ करते हैं. वे ऐसा तेज़ी से बैक/फ़ॉरवर्ड नेविगेशन की सुविधा चालू करने के लिए भी करते हैं. इससे, पेज को पूरा बार फिर से लोड करने की ज़रूरत नहीं पड़ती.
संभावित पिछली स्थितियां:
आगे की संभावित स्थितियां: |
बंद किया गया |
किसी पेज को अनलोड करने और ब्राउज़र से मेमोरी से हटाने के बाद, वह बंद की स्थिति में रहता है. इस स्थिति में कोई नए टास्क शुरू नहीं किए जा सकते. साथ ही, अगर पहले से चल रहे टास्क ज़्यादा समय तक चलते हैं, तो वे रद्द भी किए जा सकते हैं.
संभावित पिछली स्थितियां:
अगली स्थिति: |
खारिज किया गया |
किसी पेज को तब डिसकार्ड की स्थिति में रखा जाता है, जब उसे रिसॉर्स बचाने के लिए ब्राउज़र से अनलोड किया जाता है. इस स्थिति में कोई भी टास्क, इवेंट कॉलबैक या किसी भी तरह का JavaScript नहीं चलाया जा सकता. इसकी वजह यह है कि आम तौर पर, रिसॉर्स की कमी की वजह से कॉन्टेंट खारिज हो जाता है, जहां नई प्रोसेस शुरू करना मुमकिन नहीं होता. डिसकार्ड की गई स्थिति में, उपयोगकर्ता को टैब (इसमें टैब का टाइटल और फ़ेविकॉन भी शामिल है) आम तौर पर दिखता है, भले ही पेज न दिख रहा हो.
संभावित पिछली स्थितियां:
अगली स्थिति: |
इवेंट
ब्राउज़र कई इवेंट भेजते हैं, लेकिन उनमें से एक छोटा सा हिस्सा ही पेज की लाइफ़साइकल की स्थिति में हो सकने वाले बदलाव का संकेत देता है. नीचे दी गई टेबल में, उन सभी इवेंट के बारे में बताया गया है जो लाइफ़साइकल से जुड़े हैं. साथ ही, यह भी बताया गया है कि वे किन स्थितियों में हो सकते हैं और कहां से ट्रांसफ़र हो सकते हैं.
नाम | ब्यौरा |
---|---|
focus
|
किसी DOM एलिमेंट पर फ़ोकस किया गया है.
ध्यान दें:
संभावित पिछली स्थितियां:
मौजूदा स्थितियां: |
blur
|
डीओएम एलिमेंट ने फ़ोकस खो दिया है.
ध्यान दें:
संभावित पिछली स्थितियां:
मौजूदा स्थितियां: |
visibilitychange
|
दस्तावेज़ की
संभावित पिछली स्थितियां:
संभावित मौजूदा स्थितियां: |
freeze
*
|
पेज को अभी-अभी फ़्रीज़ किया गया है. पेज की टास्क सूची में, फ़्रीज़ किया जा सकने वाला टास्क शुरू नहीं होगा.
संभावित पिछली स्थितियां:
मौजूदा स्थितियां: |
resume
*
|
ब्राउज़र ने फ़्रीज़ किया हुआ पेज फिर से शुरू कर दिया है.
संभावित पिछली स्थितियां:
संभावित मौजूदा स्थितियां: |
pageshow
|
सेशन के इतिहास की एंट्री का पता लगाया जा रहा है. यह नया पेज लोड हो सकता है या
बैक/फ़ॉरवर्ड कैश मेमोरी से लिया गया कोई पेज हो सकता है. अगर पेज को बैक-फ़ॉरवर्ड कैश मेमोरी से लिया गया है, तो इवेंट की
संभावित पिछली स्थितियां:
संभावित मौजूदा स्थितियां: |
pagehide
|
सेशन के इतिहास की एंट्री का पता लगाया जा रहा है. अगर उपयोगकर्ता किसी दूसरे पेज पर जा रहा है और ब्राउज़र मौजूदा पेज को बाद में इस्तेमाल करने के लिए, बैक/फ़ॉरवर्ड कैश मेमोरी में जोड़ पा रहा है, तो इवेंट की
संभावित पिछली स्थितियां:
संभावित मौजूदा स्थितियां: |
beforeunload
|
विंडो, दस्तावेज़, और उसके संसाधन अनलोड होने वाले हैं. दस्तावेज़ अब भी दिख रहा है और इस समय इवेंट को रद्द किया जा सकता है.
अहम जानकारी:
संभावित पिछली स्थितियां:
मौजूदा स्थितियां: |
unload
|
पेज अनलोड किया जा रहा है.
चेतावनी:
संभावित पिछली स्थितियां:
संभावित मौजूदा स्थितियां: |
* से उस नए इवेंट के बारे में पता चलता है जिसे Page Lifecycle API ने तय किया है
Chrome 68 में जोड़ी गई नई सुविधाएं
पिछले चार्ट में, दो ऐसी स्थितियां दिखाई गई हैं जो उपयोगकर्ता की ओर से शुरू किए जाने के बजाय, सिस्टम से शुरू होती हैं: फ़्रोज़न और डिसकार्ड. जैसा कि पहले बताया गया है, आज-कल के ब्राउज़र कभी-कभी छिपे हुए टैब को फ़्रीज़ या खारिज कर देते हैं. हालांकि, डेवलपर को यह पता नहीं होता कि ऐसा कब हो रहा है.
डेवलपर अब Chrome 68 में, document
पर होने वाले freeze
और resume
इवेंट सुनकर देख सकते हैं कि छिपा हुआ टैब कब फ़्रीज़ हुआ और रुका हुआ है.
document.addEventListener('freeze', (event) => {
// The page is now frozen.
});
document.addEventListener('resume', (event) => {
// The page has been unfrozen.
});
Chrome 68 से document
ऑब्जेक्ट में, अब डेस्कटॉप Chrome पर एक wasDiscarded
प्रॉपर्टी शामिल है (इस समस्या में, Android सहायता को ट्रैक किया जा रहा है). यह पता लगाने के लिए कि छिपे हुए टैब में पेज को खारिज किया गया है या नहीं, पेज लोड होने के दौरान इस प्रॉपर्टी की वैल्यू की जांच की जा सकती है. ध्यान दें:
जिन पेजों को फिर से इस्तेमाल करने के लिए खारिज किया गया है उन्हें फिर से लोड करना ज़रूरी है.
if (document.wasDiscarded) {
// Page was previously discarded by the browser while in a hidden tab.
}
freeze
और resume
इवेंट में क्या करना ज़रूरी है, इस बारे में सलाह पाने के लिए हर राज्य के लिए डेवलपर के सुझाव देखें. साथ ही, खारिज किए जाने वाले पेजों को मैनेज करने और उन्हें तैयार करने का तरीका जानें.
अगले कुछ सेक्शन में इस बारे में खास जानकारी दी गई है कि ये नई सुविधाएं, वेब प्लैटफ़ॉर्म की मौजूदा स्थितियों और इवेंट में कैसे फ़िट होती हैं.
कोड में पेज की लाइफ़साइकल स्थितियों को देखने का तरीका
चालू, पैसिव, और छिपे हुए स्टेटस में, JavaScript कोड चलाया जा सकता है जो मौजूदा वेब प्लैटफ़ॉर्म एपीआई से, पेज की मौजूदा लाइफ़साइकल की स्थिति तय करता है.
const getState = () => {
if (document.visibilityState === 'hidden') {
return 'hidden';
}
if (document.hasFocus()) {
return 'active';
}
return 'passive';
};
फ़्रीज़ हुई और बंद की गई स्थितियों का पता, इवेंट लिसनर (freeze
और pagehide
) में ही रिकॉर्ड किया जा सकता है, क्योंकि इवेंट की स्थिति बदलती रहती है.
स्थिति में हुए बदलावों पर नज़र रखने का तरीका
पहले तय किए गए getState()
फ़ंक्शन के आधार पर, नीचे दिए गए कोड से पेज की लाइफ़साइकल की स्थिति में हुए सभी बदलावों को देखा जा सकता है.
// Stores the initial state using the `getState()` function (defined above).
let state = getState();
// Accepts a next state and, if there's been a state change, logs the
// change to the console. It also updates the `state` value defined above.
const logStateChange = (nextState) => {
const prevState = state;
if (nextState !== prevState) {
console.log(`State change: ${prevState} >>> ${nextState}`);
state = nextState;
}
};
// Options used for all event listeners.
const opts = {capture: true};
// These lifecycle events can all use the same listener to observe state
// changes (they call the `getState()` function to determine the next state).
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
window.addEventListener(type, () => logStateChange(getState(), opts));
});
// The next two listeners, on the other hand, can determine the next
// state from the event itself.
window.addEventListener('freeze', () => {
// In the freeze event, the next state is always frozen.
logStateChange('frozen');
}, opts);
window.addEventListener('pagehide', (event) => {
// If the event's persisted property is `true` the page is about
// to enter the back/forward cache, which is also in the frozen state.
// If the event's persisted property is not `true` the page is
// about to be unloaded.
logStateChange(event.persisted ? 'frozen' : 'terminated');
}, opts);
यह कोड तीन काम करता है:
getState()
फ़ंक्शन का इस्तेमाल करके शुरुआती स्थिति सेट करता है.- यह एक ऐसा फ़ंक्शन तय करता है जो अगली स्थिति स्वीकार करता है. कोई बदलाव होने पर, स्थिति के बदलावों को कंसोल में लॉग करता है.
- यह लाइफ़साइकल के सभी ज़रूरी इवेंट
के लिए, इवेंट लिसनर को कैप्चर करता है, जो अगली स्थिति में
logStateChange()
को पास हो जाता है.
कोड के बारे में ध्यान देने वाली बात यह है कि इवेंट को सुनने वाले सभी लोगों को window
में जोड़ा जाता है और वे सभी {capture: true}
को पास कर लेते हैं.
ऐसा होने की कुछ वजहें होती हैं. जैसे:
- सभी पेज लाइफ़साइकल इवेंट का टारगेट एक जैसा नहीं होता.
pagehide
औरpageshow
,window
को ट्रिगर होते हैं.visibilitychange
,freeze
, औरresume
,document
को ट्रिगर होते हैं. साथ ही,focus
औरblur
, अपने-अपने डीओएम एलिमेंट पर ट्रिगर होते हैं. - इनमें से ज़्यादातर इवेंट बबल नहीं होते हैं. इसका मतलब है कि कैप्चर नहीं किए जाने वाले इवेंट लिसनर को किसी एक पूर्व एलिमेंट में जोड़ा जा सकता है और सभी को ट्रैक नहीं किया जा सकता.
- कैप्चर करने का फ़ेज़, टारगेट या बबल फ़ेज़ से पहले काम करता है. इसलिए, लोगों को वहां जोड़ने से, यह पक्का करने में मदद मिलती है कि किसी दूसरे कोड के रद्द होने से पहले ही वे चले जाएं.
हर राज्य के लिए डेवलपर के सुझाव
डेवलपर के तौर पर, पेज लाइफ़साइकल की स्थितियों को समझना ज़रूरी है और उन्हें कोड में देखने का तरीका जानना भी ज़रूरी है. ऐसा इसलिए, क्योंकि आपको किस तरह का काम करना चाहिए (और नहीं करना चाहिए), यह काफ़ी हद तक इस बात पर निर्भर करता है कि आपका पेज किस स्थिति में है.
उदाहरण के लिए, अगर पेज 'छिपाए गए' स्थिति में है, तो उपयोगकर्ता को थोड़ी देर के लिए सूचना दिखाने का कोई मतलब नहीं है. यह उदाहरण तो साफ़ तौर पर दिख रहा है, लेकिन कुछ ऐसे सुझाव भी हैं जो ज़्यादा साफ़ तौर पर नहीं दिखते हैं.
स्थिति | डेवलपर के लिए सुझाव |
---|---|
Active |
उपयोगकर्ता के लिए चालू स्थिति सबसे अहम समय होती है और इस वजह से आपके पेज के लिए उपयोगकर्ता के इनपुट के हिसाब से सबसे ज़रूरी समय आ जाना चाहिए. बिना यूज़र इंटरफ़ेस (यूआई) के मुख्य थ्रेड को ब्लॉक करने वाले किसी भी काम को कुछ समय से इस्तेमाल में न होने की अवधि या किसी वेब वर्कर पर ऑफ़लोड करने से प्राथमिकता नहीं दी जानी चाहिए. |
Passive |
पैसिव स्थिति में, उपयोगकर्ता पेज के साथ इंटरैक्ट नहीं कर रहा होता है, लेकिन वह अब भी उसे देख सकता है. इसका मतलब है कि यूज़र इंटरफ़ेस (यूआई) अपडेट और ऐनिमेशन अब भी ठीक तरह से होने चाहिए. हालांकि, ये अपडेट होने का समय कम अहम होता है. जब पेज चालू से पैसिव में बदल जाता है, तो ऐप्लिकेशन की सेव नहीं की गई स्थिति को बनाए रखने का सही समय है. |
जब पेज बंद से छिपा हुआ में बदल जाता है, तो हो सकता है कि पेज को फिर से लोड किए जाने तक, वह उपयोगकर्ता से दोबारा इंटरैक्ट न करे. छिपा हुआ पेज भी वह आखिरी बदलाव होता है जिसकी निगरानी डेवलपर आसानी से कर सकते हैं. यह खास तौर पर मोबाइल पर होता है, क्योंकि उपयोगकर्ता खुद टैब या ब्राउज़र ऐप्लिकेशन को बंद कर सकते हैं. ऐसे मामलों में इसका मतलब है कि आपको छिपाई गई स्थिति को उपयोगकर्ता के सेशन के खत्म होने की संभावना के तौर पर मानना चाहिए. दूसरे शब्दों में, ऐप्लिकेशन के सेव नहीं किए गए स्टेटस को बनाए रखें और आंकड़ों का जो डेटा नहीं भेजा गया है उसे भेजें. आपको यूज़र इंटरफ़ेस (यूआई) अपडेट करना भी बंद कर देना चाहिए (क्योंकि वे उपयोगकर्ता को नहीं दिखेंगे). साथ ही, आपको ऐसे टास्क बंद कर देने चाहिए जिन्हें उपयोगकर्ता को बैकग्राउंड में नहीं चलाना है. |
|
Frozen |
फ़्रीज़ होने पर, टास्क की सूची में फ़्रीज़ किए जा सकने वाले टास्क तब तक निलंबित रहते हैं, जब तक पेज को फ़्रीज़ नहीं किया जाता. हो सकता है कि ऐसा कभी न हो (उदाहरण के लिए, अगर पेज खारिज कर दिया गया हो). इसका मतलब है कि जब कोई पेज छिपा हुआ से फ़्रोज़न में बदलता है, तो यह ज़रूरी है कि आप किसी भी टाइमर को बंद कर दें या ऐसे कनेक्शन को बंद कर दें जो फ़्रीज़ किए गए हों, उसी ऑरिजिन में मौजूद दूसरे खुले हुए टैब पर असर डाल सकते हों या पेज को बैक-फ़ॉरवर्ड कैश मेमोरी में रखने की ब्राउज़र की क्षमता पर असर डाल सकते हों. खास तौर पर, यह ज़रूरी है कि:
अगर पेज को खारिज करके बाद में फिर से लोड किया जाता है, तो आपको उस डाइनैमिक व्यू स्थिति (जैसे कि अनंत सूची वाले व्यू में स्क्रोल की पोज़िशन) को
अगर वह पेज फ़्रीज़ किया गया से वापस छिपा हुआ में बदल जाता है, तो आपके पास किसी भी बंद कनेक्शन को फिर से खोलने का विकल्प होता है. इसके अलावा, जब पेज को फ़्रीज़ किया गया था, तो उस पोल को फिर से शुरू किया जा सकता है. |
Terminated |
आम तौर पर, किसी पेज के बंद किए गए वर्शन पर ट्रांज़िशन होने पर, आपको कुछ भी करने की ज़रूरत नहीं होती. उपयोगकर्ता की कार्रवाई की वजह से, अनलोड होने वाले पेज बंद की स्थिति डालने से पहले, हमेशा छिपी हुई स्थिति से गुज़रते हैं. इसलिए, छिपी हुई स्थिति ही सेशन खत्म होने वाले लॉजिक (जैसे, ऐप्लिकेशन की बनी रहने की स्थिति और आंकड़ों को रिपोर्ट करना) की कार्रवाई की जानी चाहिए. साथ ही, जैसा कि छिपे हुए स्टेटस के लिए सुझावों में बताया गया है, डेवलपर के लिए यह समझना बहुत ज़रूरी है कि बंद की गई स्थिति पर ट्रांज़िशन का कई मामलों (खास तौर पर मोबाइल पर) पर सही तरीके से पता नहीं लगाया जा सकता. इसलिए, हो सकता है कि वे डेवलपर डेटा खो दें जो सदस्यता खत्म करने के इवेंट (उदाहरण के लिए, |
Discarded |
जब किसी पेज को खारिज किया जा रहा हो, तो डेवलपर को उसके डिसिडेंट किए गए स्टेटस की जानकारी नहीं मिलती. इसकी वजह यह है कि आम तौर पर, पेजों को रिसॉर्स की कमी की वजह से खारिज कर दिया जाता है. साथ ही, ज़्यादातर मामलों में सिर्फ़ स्क्रिप्ट को चलाने के लिए, पेज को अनफ़्रीज़ करने की सुविधा भी नहीं होती. इस वजह से, आपको बदलाव को छिपाए गए से फ़्रीज़ किए जाने की संभावना के लिए तैयार करना होगा. इसके बाद,
|
एक बार फिर बता दें कि सभी ब्राउज़र में लाइफ़साइकल इवेंट की विश्वसनीयता और उनका क्रम एक जैसा नहीं है. इसलिए, टेबल में दी गई सलाह को अपनाने का सबसे आसान तरीका PageLifecycle.js का इस्तेमाल करना है.
बचने के लिए, लेगसी लाइफ़साइकल एपीआई
जहां भी संभव हो, इन इवेंट से बचना चाहिए.
अनलोड इवेंट
कई डेवलपर, unload
इवेंट को गारंटी वाले कॉलबैक के तौर पर देखते हैं और स्टेटस को सेव करने और आंकड़ों का डेटा भेजने के लिए, इसे सेशन खत्म होने के सिग्नल के तौर पर इस्तेमाल करते हैं. हालांकि, ऐसा करना बहुत ही भरोसेमंद है, खास तौर पर मोबाइल पर! unload
इवेंट, अनलोड की कई सामान्य स्थितियों में सक्रिय नहीं होता है. इनमें मोबाइल पर टैब स्विचर से किसी टैब को बंद करना या ऐप्लिकेशन स्विचर से ब्राउज़र ऐप्लिकेशन को बंद करना शामिल है.
इस वजह से, सेशन कब खत्म होता है, यह तय करने के लिए visibilitychange
इवेंट पर भरोसा करना हमेशा बेहतर होता है. साथ ही, छिपी हुई स्थिति को ऐप्लिकेशन और उपयोगकर्ता के डेटा को सेव करने का आखिरी समय के तौर पर देखना बेहतर होता है.
इसके अलावा, रजिस्टर किए गए unload
इवेंट हैंडलर (onunload
या addEventListener()
के ज़रिए) की मौजूदगी से ब्राउज़र, पेजों को बैक/फ़ॉरवर्ड कैश मेमोरी में नहीं रख सकते, ताकि वे तेज़ी से बैक और फ़ॉरवर्ड लोड हो सकें.
सभी मॉडर्न ब्राउज़र में, हमारा सुझाव है कि आप हमेशा पेज के अनलोड होने का पता लगाने के लिए, unload
इवेंट के बजाय pagehide
इवेंट का इस्तेमाल करें. इसे खत्म किया गया स्टेटस भी कहा जाता है. अगर आपको
Internet Explorer के वर्शन 10 और इससे पहले के वर्शन पर काम करना चाहिए, तो आपको pagehide
इवेंट का पता लगाने की सुविधा देनी चाहिए. साथ ही, unload
का इस्तेमाल सिर्फ़ तब करना चाहिए, जब ब्राउज़र pagehide
पर काम न करता हो:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
window.addEventListener(terminationEvent, (event) => {
// Note: if the browser is able to cache the page, `event.persisted`
// is `true`, and the state is frozen rather than terminated.
});
beforeunload इवेंट
beforeunload
इवेंट में भी unload
इवेंट से मिलती-जुलती समस्या है. पुराने दौर में, beforeunload
इवेंट होने पर, हो सकता है कि पेजों को बैक/फ़ॉरवर्ड कैश मेमोरी की सुविधा के लिए ऐक्सेस न किया जा सके. मॉडर्न ब्राउज़र पर
यह पाबंदी नहीं होती. हालांकि, सावधानी के तौर पर, कुछ ब्राउज़र पेज को बैक-फ़ॉरवर्ड कैश मेमोरी में सेव करने की कोशिश करते समय, beforeunload
इवेंट को ट्रिगर नहीं करेंगे. इसका मतलब है कि इवेंट, सेशन खत्म होने के सिग्नल के तौर पर भरोसेमंद नहीं है.
इसके अलावा, कुछ ब्राउज़र (इनमें Chrome भी शामिल है) के लिए beforeunload
इवेंट को चालू होने की अनुमति देने से पहले, पेज पर उपयोगकर्ता के इंटरैक्शन की ज़रूरत होती है. इससे, पेज की विश्वसनीयता पर असर पड़ता है.
beforeunload
और unload
के बीच एक अंतर यह है कि beforeunload
का कानूनी तौर पर इस्तेमाल किया जाता है. उदाहरण के लिए, जब उपयोगकर्ता को चेतावनी देनी हो कि
उनके बदलाव सेव नहीं किए गए हैं, तो पेज को अनलोड करना जारी रखने पर वे बदलाव नहीं कर पाएंगे.
beforeunload
को इस्तेमाल करने की सही वजहें हैं, इसलिए हमारा सुझाव है कि आप
सिर्फ़ तब beforeunload
लिसनर को जोड़ें, जब उपयोगकर्ता के पास सेव नहीं किए गए बदलाव हों. इसके बाद, उन्हें सेव करने के तुरंत बाद हटा दें.
दूसरे शब्दों में, ऐसा न करें (क्योंकि यह बिना किसी शर्त के, beforeunload
लिसनर को जोड़ता है):
addEventListener('beforeunload', (event) => {
// A function that returns `true` if the page has unsaved changes.
if (pageHasUnsavedChanges()) {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
}
});
इसके बजाय, ऐसा करें (क्योंकि ज़रूरत पड़ने पर ही यह beforeunload
लिसनर को जोड़ता है और ऐसा न होने पर इसे हटा देता है):
const beforeUnloadListener = (event) => {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
};
// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
addEventListener('beforeunload', beforeUnloadListener);
});
// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
removeEventListener('beforeunload', beforeUnloadListener);
});
अक्सर पूछे जाने वाले सवाल
"लोड हो रहा है" स्थिति क्यों नहीं दिख रही है?
Page Lifecycle API के मुताबिक स्थितियां अलग-अलग और म्युचुअली एक्सक्लूसिव होती हैं. किसी पेज को ऐक्टिव, पैसिव या छिपे हुए स्टेटस में लोड किया जा सकता है. पेज के लोड होने से पहले उसकी स्थिति बदली जा सकती है या उसे बंद भी किया जा सकता है. इसलिए, इस उदाहरण में पेज लोड होने का कोई मतलब नहीं बनता.
छिपाने पर मेरा पेज ज़रूरी काम करता है, मैं उसे फ़्रीज़ होने या खारिज होने से कैसे रोकूं?
वेब पेजों को छिपे हुए मोड में चलते हुए फ़्री न होने की कई वजहें हो सकती हैं. सबसे सटीक उदाहरण ऐसा ऐप्लिकेशन है जो संगीत चलाता है.
कुछ मामलों में Chrome के लिए, पेज को खारिज करना जोखिम भरा हो सकता है. जैसे, ऐसा फ़ॉर्म जिसमें सबमिट नहीं किए गए उपयोगकर्ता का इनपुट हो या इसमें ऐसा beforeunload
हैंडलर हो जो पेज के अनलोड होने पर चेतावनी देता हो.
फ़िलहाल, पेजों को खारिज करते समय Chrome का इस्तेमाल बहुत कम किया जाएगा. ऐसा सिर्फ़ तब किया जा सकेगा, जब उसे पूरा भरोसा हो कि उसका इस्तेमाल करने वालों पर कोई असर नहीं होगा. उदाहरण के लिए, ऐसे पेजों को तब तक खारिज नहीं किया जाएगा, जिनके लिए छिपी हुई स्थिति में, नीचे दिया गया कोई भी काम किया गया हो.
- ऑडियो चलाया जा रहा है
- WebRTC का इस्तेमाल करना
- टेबल का टाइटल या फ़ेविकॉन अपडेट करना
- सूचनाएं दिखाई जा रही हैं
- पुश नोटिफ़िकेशन भेजे जा रहे हैं
किसी टैब को सुरक्षित तरीके से फ़्रीज़ या खारिज किया जा सकता है या नहीं, यह तय करने के लिए इस्तेमाल की जाने वाली मौजूदा सुविधाओं की सूची के लिए, यह देखें: Chrome में फ़्रीज़िंग और खारिज करने के तरीके.
बैक/फ़ॉरवर्ड कैश मेमोरी क्या है?
बैक/फ़ॉरवर्ड कैश मेमोरी का इस्तेमाल, नेविगेशन ऑप्टिमाइज़ेशन के लिए किया जाता है. कुछ ब्राउज़र इस सुविधा को लागू करते समय, 'वापस जाएं' और 'आगे बढ़ें' बटन को ज़्यादा तेज़ी से इस्तेमाल करते हैं.
जब कोई उपयोगकर्ता किसी पेज से दूर नेविगेट करता है, तो ये ब्राउज़र उस पेज के वर्शन को फ़्रीज़ कर देते हैं. इससे, अगर उपयोगकर्ता 'वापस जाएं' या 'आगे बढ़ें' बटन का इस्तेमाल करके वापस नेविगेट करता है, तो इसे तुरंत फिर से शुरू किया जा सकता है. याद रखें कि unload
इवेंट हैंडलर जोड़ने से, यह ऑप्टिमाइज़ेशन नहीं हो पाता.
सभी इंटेंट और कामों के लिए, यह फ़्रीज़िंग ठीक उसी तरह काम करती है, जैसे कि फ़्रीज़िंग ब्राउज़र, सीपीयू/बैटरी बचाने के लिए काम करते हैं. इस वजह से, इसे फ़्रीज़ लाइफ़साइकल स्थिति का हिस्सा माना जाता है.
अगर मैं फ़्रीज़ किए गए या खत्म हो चुके स्टेटस में एसिंक्रोनस एपीआई नहीं चला सकता, तो मैं IndexedDB में डेटा कैसे सेव करूं?
फ़्रीज़ और बंद किए गए स्टेटस में, पेज की टास्क सूची में फ़्रीज़ किए जा सकने वाले टास्क निलंबित कर दिए जाते हैं. इसका मतलब है कि IndexedDB जैसे एसिंक्रोनस और कॉलबैक-आधारित एपीआई सही तरीके से इस्तेमाल नहीं किए जा सकते.
आने वाले समय में, हम IDBTransaction
ऑब्जेक्ट में commit()
का तरीका जोड़ेंगे. इससे डेवलपर बेहतर तरीके से ऐसे ट्रांज़ैक्शन कर पाएंगे जिन्हें सिर्फ़ राइट-ओनली ट्रांज़ैक्शन के लिए इस्तेमाल किया जा सकता है. इनमें कॉलबैक की ज़रूरत नहीं होती. दूसरे शब्दों में, अगर डेवलपर सिर्फ़
IndexedDB को डेटा लिख रहा है और वह कॉम्प्लेक्स ट्रांज़ैक्शन नहीं कर रहा है जिसमें रीड
और राइट शामिल हैं, तो commit()
वाला तरीका, टास्क की सूचियों के निलंबित होने से पहले पूरा कर पाएगा (यह मानते हुए कि IndexedDB डेटाबेस पहले से खुला है).
हालांकि, आज के समय में काम करने वाले कोड के लिए, डेवलपर के पास दो विकल्प हैं:
- सेशन स्टोरेज का इस्तेमाल करें: सेशन स्टोरेज सिंक्रोनस होता है और यह पेज खारिज करने के दौरान बना रहता है.
- अपने सर्विस वर्कर से IndexedDB का इस्तेमाल करें: पेज को खत्म या खारिज करने के बाद, सर्विस वर्कर,IndexedDB में डेटा सेव कर सकता है.
freeze
याpagehide
इवेंट लिसनर में,postMessage()
की मदद से आपके सर्विस वर्कर को डेटा भेजा जा सकता है. सर्विस वर्कर, डेटा सेव करने के काम को संभाल सकता है.
अपने ऐप्लिकेशन को फ़्रीज़ और खारिज की गई स्थितियों में टेस्ट करना
यह जांचने के लिए कि आपका ऐप्लिकेशन, फ़्रीज़ और खारिज की गई स्थितियों में कैसे काम करता है, chrome://discards
पर जाकर अपने किसी भी खुले हुए टैब को असल में फ़्रीज़ या खारिज किया जा सकता है.
इससे यह पक्का किया जा सकता है कि आपका पेज, freeze
और resume
इवेंट को सही तरीके से हैंडल करता है. साथ ही, खारिज करने के बाद पेज फिर से लोड होने पर document.wasDiscarded
फ़्लैग भी ठीक से हैंडल करता है.
खास जानकारी
ऐसे डेवलपर जो अपने उपयोगकर्ताओं के डिवाइस के सिस्टम संसाधनों का सम्मान करना चाहते हैं उन्हें पेज लाइफ़साइकल की स्थितियों को ध्यान में रखकर अपने ऐप्लिकेशन बनाने चाहिए. यह ज़रूरी है कि वेब पेज ऐसी स्थितियों में सिस्टम के बहुत ज़्यादा संसाधनों का इस्तेमाल न करें जिनकी उम्मीद उपयोगकर्ता न करे
जितने ज़्यादा डेवलपर नए पेज लाइफ़साइकल एपीआई को लागू करना शुरू करेंगे, तब तक ब्राउज़र के लिए इस्तेमाल न किए जा रहे पेजों को फ़्रीज़ और खारिज करना उतना ही सुरक्षित रहेगा. इसका मतलब है कि ब्राउज़र कम मेमोरी, सीपीयू, बैटरी, और नेटवर्क संसाधनों का इस्तेमाल करेंगे. यह उपयोगकर्ताओं के लिए फ़ायदेमंद है.