पेज लाइफ़साइकल एपीआई

Philip Walton
Philip Walton

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 68.
  • Edge: 79.
  • Firefox: यह सुविधा काम नहीं करती.
  • Safari: यह सुविधा काम नहीं करती.

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

बैकग्राउंड

ऐप्लिकेशन लाइफ़साइकल, आधुनिक ऑपरेटिंग सिस्टम के लिए संसाधनों को मैनेज करने का मुख्य तरीका है. Android, iOS, और Windows के नए वर्शन पर, ओएस कभी भी ऐप्लिकेशन को शुरू और बंद कर सकता है. इससे, इन प्लैटफ़ॉर्म को संसाधनों को बेहतर तरीके से मैनेज करने और उन्हें फिर से बांटने में मदद मिलती है, ताकि उपयोगकर्ता को ज़्यादा से ज़्यादा फ़ायदा मिल सके.

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

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

असल में, आज के ब्राउज़र पहले से ही बैकग्राउंड टैब में मौजूद पेजों के लिए, संसाधनों को बचाने क�� लिए सक्रिय कदम उठाते हैं. साथ ही, कई ब्राउज़र (खास तौर पर Chrome) इस तरह के और भी कदम उठाना चाहते हैं, ताकि संसाधनों का इस्तेमाल कम से कम हो.

समस्या यह है कि डेवलपर के पास, सिस्टम की ओर से किए जाने वाले इस तरह के इंटरवेंशन के लिए तैयारी करने का कोई तरीका नहीं है. इसके अलावा, उन्हें यह भी नहीं पता कि ये इंटरवेंशन हो रहे हैं. इसका मतलब है कि ब्राउज़र को सावधानी से काम करना चाहिए, नहीं तो वेब पेजों के काम न करने का खतरा हो सकता है.

पेज लाइफ़साइकल एपीआई, इस समस्या को हल करने की कोशिश करता है:

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

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

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

पेज के लाइफ़साइकल की स्थितियों और इवेंट के बारे में खास जानकारी

पेज के लाइफ़साइकल की सभी स्थितियां अलग-अलग होती हैं और एक-दूसरे से अलग होती हैं. इसका मतलब है कि कोई पेज एक समय में सिर्फ़ एक ही स्थिति में हो सकता ��ै. आम तौर पर, किसी पेज के लाइफ़साइकल की स्थिति में होने वाले ज़्यादातर बदलावों को डीओएम इवेंट की मदद से देखा जा सकता है. अपवादों के बारे में जानने के लिए, हर स्थिति के लिए डेवलपर के सुझाव देखें.

पेज के लाइफ़साइकल की स्थितियों के साथ-साथ, उन इवेंट के बारे में बताने का सबसे आसान तरीका, डायग्राम का इस्तेमाल करना है जो उनके बीच ट्रांज़िशन का सिग्नल देते हैं:

इस दस्तावेज़ में स्थिति और इवेंट फ़्लो को विज़ुअल तरीके से दिखाया जाता है.
पेज लाइफ़साइकल एपीआई की स्थिति और इवेंट फ़्लो.

राज्य

इस टेबल में, हर राज्य के बारे में पूरी जानकारी दी गई है. इसमें उन संभावित स्थितियों की सूची भी होती है जो बदलाव से पहले और बाद में आ सकती हैं. साथ ही, डेवलपर बदलावों को देखने के लिए इवेंट का इस्तेमाल कर सकते हैं.

स्थिति ब्यौरा
ऐक्टिव

अगर कोई पेज दिख रहा है और उस पर इनपुट फ़ोकस है, तो वह चालू स्थिति में होता है.

पिछली संभावित स्थितियां:
पैसिव (focus इवेंट के ज़रिए)
फ़्रीज़ की गई (resume इवेंट के ज़रिए, फिर pageshow इवेंट)

अगली संभावित स्थितियां:
पैसिव ( blur इवेंट के ज़रिए)

काम नहीं कर रहा

अगर कोई पेज दिख रहा है और उस पर इनपुट फ़ोकस नहीं है, तो वह पैसिव स्थिति में होता है.

पिछली संभावित स्थितियां:
चालू है (blur इवेंट के ज़रिए)
छिपा हुआ है ( visibilitychange इवेंट के ज़रिए)
फ़्रीज़ किया गया है (resume इवेंट के बाद, pageshow इवेंट के ज़रिए)

अगली संभावित स्थितियां:
चालू है (focus इवेंट के ज़रिए)
छिपा हुआ ( visibilitychange इवेंट के ज़रिए)

छिपे हुए

अगर कोई पेज नहीं दिख रहा है (और उसे फ़्रीज़ नहीं किया गया है, खारिज नहीं किया गया है या बंद नहीं किया गया है), तो वह छिपाया गया स्थिति में है.

पिछली संभावित स्थितियां:
पैसिव ( visibilitychange इवेंट के ज़रिए)
फ़्रीज़ किया गया (resume इवेंट के ज़रिए, फिर pageshow इवेंट में)

इसके बाद की संभावित स्थितियां:
पैसिव ( visibilitychange इवेंट के ज़रिए)
फ़्रीज़ किया गया (freeze इवेंट के ज़रिए)
खारिज किया गया (कोई इवेंट ट्रिगर नहीं हुआ)
बंद किया गया (कोई इवेंट ट्रिगर नहीं हुआ)

फ़्रीज़ हो गया

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

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

पिछली संभावित स्थितियां:
छिपा हुआ (freeze इवेंट के ज़रिए)

इसके बाद की संभावित स्थितियां:
चालू (resume इवेंट के ज़रिए, फिर pageshow इवेंट के ज़रिए)
पैसिव (resume इवेंट के ज़रिए, फिर pageshow इवेंट के ज़रिए)
छिपा हुआ (resume इवेंट के ज़रिए)
खारिज किया गया (कोई इवेंट ट्रिगर नहीं हुआ)

समझौता खत्म हो गया है

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

पिछली संभावित स्थितियां:
छिपाया गया (pagehide इवेंट के ज़रिए)

अगली स्थितियां:
कोई नहीं

खारिज किया गया

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

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

पिछली संभावित स्थितियां:
छिपा हुआ (कोई इवेंट ट्रिगर नहीं हुआ)
फ़्रीज़ किया गया (कोई इवेंट ट्रिगर नहीं हुआ)

अगली स्थितियां:
कोई नहीं

इवेंट

ब्राउज़र कई इवेंट डिस्पैच करते हैं, लेकिन उनमें से सिर्फ़ कुछ ही इवेंट, पेज लाइफ़साइकल की स्थिति में संभावित बदलाव का संकेत देते हैं. नीचे दी गई टेबल में, लाइफ़साइकल से जुड़े सभी इवेंट के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि ये इवेंट किन स्टेटस में ट्रांज़िशन कर सकते हैं.

नाम विवरण
focus

किसी डीओएम एलिमेंट को फ़ोकस मिला है.

ध्यान दें: यह ज़रूरी नहीं है कि focus इवेंट का मतलब है कि राज्य में कोई बदलाव हुआ है. यह सिर्फ़ तब स्थिति में बदलाव का सिग्नल देता है, जब पेज पर पहले इनपुट फ़ोकस नहीं था.

पिछली स्थितियां:
पैसिव

मौजूदा स्थितियां:
चालू है

blur

किसी DOM एलिमेंट का फ़ोकस हट गया है.

ध्यान दें: blur इवेंट से, ज़रूरी नहीं है कि स्टेटस में बदलाव का सिग्नल मिले. यह सिर्फ़ तब स्थिति में बदलाव का सिग्नल देता है, जब पेज पर इनपुट फ़ोकस न हो. इसका मतलब है कि पेज पर फ़ोकस, एक एलिमेंट से दूसरे एलिमेंट पर स्विच नहीं हुआ है.

पिछली स्थितियां:
चालू है

मौजूदा स्थितियां:
पैसिव

visibilitychange

दस्तावेज़ की visibilityState वैल्यू बदल गई है. ऐसा तब हो सकता है, जब कोई उपयोगकर्ता किसी नए पेज पर जाए, टैब स्विच करे, किसी टैब को बंद करे, ब्राउज़र को छोटा करे या बंद करे या मोबाइल ऑपरेटिंग सिस्टम पर ऐप्लिकेशन स्विच करे.

पिछली संभावित स्थितियां:
पैसिव
छिपाया गया

मौजूदा स्थितियां:
पैसिव
छिपा हुआ

freeze *

पेज अभी-अभी फ़्रीज़ हुआ है. पेज की टास्क सूचियों में मौजूद, फ़्रीज़ किया जा सकने वाला कोई भी टास्क शुरू नहीं किया जाएगा.

पिछली स्थितियां:
छिपा हुआ

मौजूदा स्थितियां:
फ़्रीज़ की गई

resume *

ब्राउज़र ने फ़्रीज़ हो चुके पेज को फिर से शुरू कर दिया है.

पिछली संभावित स्थितियां:
फ़्रीज़ हुई

मौजूदा स्थितियां:
चालू है (अगर इसके बाद, pageshow इवेंट आता है)
पैसिव है (अगर इसके बाद, pageshow इवेंट आता है)
छिपा हुआ है

pageshow

सेशन के इतिहास की किसी एंट्री पर जाया जा रहा है.

यह कोई नया पेज लोड हो सकता है या बैक/फ़ॉरवर्ड कैश मेमोरी से लिया गया पेज हो सकता है. अगर पेज को बैक/फ़ॉरवर्ड कैश मेमोरी से लिया गया था, तो इवेंट की persisted प्रॉपर्टी true होगी. अगर ऐसा नहीं है, तो वह false होगी.

पिछली संभावित स्थितियां:
फ़्रीज़ किया गया (resume इवेंट भी ट्रिगर हो जाएगा)

मौजूदा स्थितियां:
चालू है
बंद है
छिपा हुआ है

pagehide

सेशन के इतिहास की किसी एंट्री से ट्रैवर्स किया जा रहा है.

अगर उपयोगकर्ता किसी दूसरे पेज पर जा रहा है और ब्राउज़र, मौजूदा पेज को बैक/फ़ॉरवर्ड कैश मेमोरी में जोड़ पा रहा है, ताकि बाद में उसका फिर से इस्तेमाल किया जा सके, तो इवेंट की persisted प्रॉपर्टी true होती है. जब true, पेज फ़्रीज़ हो जाता है. इसके अलावा, बंद होने पर भी ऐसा होता है.

पिछली स्थितियां:
छिपा हुआ

मौजूदा स्थितियां:
फ़्रीज़ किया गया (event.persisted सही है, freeze इवेंट इसके बाद होता है)
बंद किया गया (event.persisted गलत है, unload इवेंट इसके बाद होता है)

beforeunload

विंडो, दस्तावेज़, और इसके संसाधन अनलोड होने वाले हैं. दस्तावेज़ अब भी दिख रहा है और इस समय इवेंट को रद्द किया जा सकता है.

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

पिछली स्थितियां:
छिपा हुआ

मौजूदा स्थितियां:
समाप्त

unload

पेज को अनलोड किया जा रहा है.

चेतावनी: 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

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

जब पेज की स्थिति चालू से बंद में बदलती है, तो ऐप्लिकेशन की सेव नहीं की गई स्थिति को बनाए रखने का यह एक अच्छा समय होता है.

Hidden

जब पेज पैसिव से छिपा हुआ हो जाता है, तो हो सकता है कि जब तक पेज को फिर से लोड नहीं किया जाता, तब तक वह इसके साथ दोबारा इंटरैक्ट न करे.

छिपा हुआ स्टेटस में ट्रांज़िशन, अक्सर आखिरी स्टेटस बदलाव होता है, ������े ��ेवलपर ��र����ेम���� तरीके से देख सकते हैं. यह बात खास तौर पर मोबाइल पर ज़्यादा सही है, क्योंकि उपयोगकर्ता टैब या ब्राउज़र ऐप्लिकेशन को बंद कर सकते हैं. साथ ही, ऐसे मामलों में beforeunload, pagehide, और unload इवेंट ट्रिगर नहीं होते.

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

आपको यूज़र इंटरफ़ेस (यूआई) के अपडेट भी बंद कर देने चाहिए, क्योंकि उपयोगकर्ता को ये अपडेट नहीं दिखेंगे. साथ ही, आपको ऐसे सभी टास्क भी बंद कर देने चाहिए जिन्हें उपयोगकर्ता बैकग्राउंड में नहीं चलाना चाहता.

Frozen

फ़्रीज़ की स्थिति में, टास्क की सूचियों में मौजूद फ़्रीज़ किए जा सकने वाले टास्क तब तक निलंबित रहते हैं, जब तक पेज को अनफ़्रीज़ नहीं किया जाता. ऐसा कभी भी नहीं हो सकता (उदाहरण के लिए, अगर पेज को खारिज कर दिया जाता है).

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

खास तौर पर, यह ज़रूरी है कि आप:

  • सभी खुले हुए IndexedDB कनेक्शन बंद करें.
  • खुले BroadcastChannel कनेक्शन बंद करें.
  • चालू WebRTC कनेक्शन बंद करें.
  • किसी भी नेटवर्क पोलिंग को रोकें या किसी भी खुले वेब स��केट कनेक्शन को बंद करें.
  • सभी वेब लॉक हटाएं.

आपको sessionStorage (या commit() के ज़रिए IndexedDB) में, किसी भी डाइनैमिक व्यू स्टेटस (जैसे, अनलिमिटेड सूची व्यू में स्क्रोल की स्थिति) को भी सेव करना चाहिए. ऐसा तब करना चाहिए, जब आपको पेज को खारिज करने और बाद में फिर से लोड करने पर, उसे वापस लाना हो.

अगर पेज फ़्रीज़ किया गया से छिपा हुआ पर वापस ट्रांज़िशन करता है, तो बंद किए गए किसी भी कनेक्शन को फिर से खोला जा सकता है या पेज के फ़्रीज़ होने पर रोके गए किसी भी पोलिंग को फिर से शुरू किया जा सकता है.

Terminated

आम तौर पर, जब कोई पेज बंद स्थिति में ट्रांज़िशन होता है, तो आपको कोई कार्रवाई करने की ज़रूरत नहीं होती.

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

साथ ही, छिपी हुई स्थिति के लिए सुझावों में बताया गया है कि डेवलपर को यह समझना बहुत ज़रूरी है कि कई मामलों में (खास तौर पर मोबाइल पर), बंद स्थिति में ट्रांज़िशन का पता नहीं लगाया जा सकता. इसलिए, डेवलपर को beforeunload, pagehide, और unload जैसे बंद होने के इवेंट पर निर्भर नहीं रहना चाहिए, क्योंकि ऐसा करने पर डेटा का नुकसान हो सकता है.

Discarded

जब किसी पेज को खारिज किया जा रहा हो, तब डेवलपर डिसकार्ड की गई स्थिति की जांच नहीं कर सकते. इसकी वजह यह है कि आम तौर पर, पेजों को संसाधन की कमी की वजह से हटा दिया जाता है. साथ ही, ज़्यादातर मामलों में, किसी पेज को सिर्फ़ इसलिए अनफ़्रीज़ नहीं किया जा सकता, ताकि पेज हटाने के इवेंट के जवाब में स्क्रिप्ट चल सके.

इसलिए, आपको छिपाया गया से फ़्रीज़ किया गया में बदलाव करने पर, पेज को ��ारिज किए जाने की संभावना के लिए तैयार रहना चाहिए. इसके बाद, पेज लोड होने के समय, खारिज किए गए पेज को वापस लाने के लिए, document.wasDiscarded को चुनें.

हम फिर से बताना चाहते हैं कि लाइफ़साइकल इवेंट की भरोसेमंदता और क्रम, सभी ब्राउज़र में एक जैसा लागू नहीं होता. इसलिए, टेबल में दिए गए सुझावों को अपनाने का सबसे आसान तरीका, PageLifecycle.js का इस्तेमाल करना है.

इन लेगसी लाइफ़साइकल एपीआई से बचें

जहां भी हो सके, इन इवेंट से बचना चाहिए.

अनलोड इवेंट

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

इस वजह से, सेशन के खत्म होने का पता लगाने के लिए, visibilitychange इवेंट पर भरोसा करना हमेशा बेहतर होता है. साथ ही, छिपी हुई स्थिति को ऐप्लिकेशन और उपयोगकर्ता का डेटा सेव करने के लिए सबसे सही समय माना जाना चाहिए.

इसके अलावा, onunload या addEventListener() के ज़रिए रजिस्टर किए गए unload इवेंट हैंडलर की मौजूदगी से, ब्राउज़र को पेजों को बैक/फ़ॉरवर्ड कैश मेमोरी में सेव करने से रोका जा सकता है. इससे, पेजों को तेज़ी से आगे और पीछे लोड करने में मदद मिलती है.

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

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 Listener को बिना किसी शर्त के जोड़ दिया जाता है:

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 पर जाएं. इसके बाद, अपने किसी भी खुले टैब को फ़्रीज़ या खारिज करें.

Chrome का यूज़र इंटरफ़ेस (यूआई)
Chrome का यूज़र इंटरफ़ेस

इससे आपको यह पक्का करने में मदद मिलती है कि आपका पेज, freeze और resume इवेंट को सही तरीके से मैनेज करता है. साथ ही, पेजों को खारिज करने के बाद, जब पेज फिर से लोड होते हैं, तब document.wasDiscarded फ़्लैग को सही तरीके से हैंडल किया जाता है.

खास जानकारी

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

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