उपयोगकर्ता चाहते हैं कि ऐप्लिकेशन तेज़ी से लोड हों और रिस्पॉन्सिव हों. अगर किसी ऐप्लिकेशन को चालू होने में ज़्यादा समय लगता है, तो वह इस उम्मीद पर खरा नहीं उतरता. इससे उपयोगकर्ताओं को निराशा हो सकती है. इस तरह के खराब अनुभव की वजह से, उपयोगकर्ता Play Store पर आपके ऐप्लिकेशन को खराब रेटिंग दे सकता है. इसके अलावा, वह आपके ऐप्लिकेशन का इस्तेमाल करना भी बंद कर सकता है.
इस पेज पर, आपके ऐप्लिकेशन के लॉन्च होने में लगने वाले समय को ऑप्टिमाइज़ करने के बारे में जानकारी दी गई है. इसमें लॉन्च प्रोसेस की खास जानकारी, स्टार्टअप परफ़ॉर्मेंस को प्रोफ़ाइल करने का तरीका, और स्टार्टअप में लगने वाले समय से जुड़ी कुछ सामान्य समस्याएं शामिल हैं. साथ ही, उन्हें हल करने के बारे में सलाह भी दी गई है.
ऐप्लिकेशन के स्टार्टअप की अलग-अलग स्थितियों के बारे में जानकारी
ऐप्लिकेशन को तीन स्थितियों में लॉन्च किया जा सकता है: कोल्ड स्टार्ट, वॉर्म स्टार्ट या हॉट स्टार्ट. हर स्थिति से यह तय होता है कि उपयोगकर्ता को आपका ऐप्लिकेशन दिखने में कितना समय लगेगा. कोल्ड स्टार्ट में, आपका ऐप्लिकेशन शुरू से शुरू होता है. अन्य राज्यों में, सिस्टम को बैकग्राउंड में चल रहे ऐप्लिकेशन को फ़ोरग्राउंड में लाना होगा.
हमारा सुझाव है कि आप हमेशा कोल्ड स्टार्ट के अनुमान के आधार पर ऑप्टिमाइज़ करें. ऐसा करने से, वार्म और हॉट स्टार्ट की परफ़ॉर्मेंस भी बेहतर हो सकती है.
ऐप्लिकेशन को तेज़ी से चालू करने के लिए ऑप्टिमाइज़ करने के लिए, यह समझना ज़रूरी है कि सिस्टम और ऐप्लिकेशन लेवल पर क्या हो रहा है. साथ ही, यह भी समझना ज़रूरी है कि ये दोनों लेवल, इन सभी स्थितियों में कैसे इंटरैक्ट करते हैं.
ऐप्लिकेशन के शुरू होने में लगने वाले समय का पता लगाने के लिए, दो अहम मेट्रिक इस्तेमाल की जाती हैं: शुरुआती डिसप्ले में लगने वाला समय (टीटीआईडी) और पूरी तरह से रेंडर होने में लगने वाला समय (टीटीएफ़डी). टीटीआईडी, पहला फ़्रेम दिखने में लगने वाला समय होता है. वहीं, टीटीएफ़डी, ऐप्लिकेशन के पूरी तरह से इंटरैक्टिव होने में लगने वाला समय होता है. ये दोनों ही मेट्रिक ज़रूरी हैं. टीटीआईडी से उपयोगकर्ता को पता चलता है कि ऐप्लिकेशन लोड हो रहा है. वहीं, टीटीएफ़डी से पता चलता है कि ऐप्लिकेशन का इस्तेमाल कब किया जा सकता है. अगर इनमें से किसी भी प्रोसेस में ज़्यादा समय लगता है, तो हो सकता है कि उपयोगकर्ता आपका ऐप्लिकेशन पूरी तरह लोड होने से पहले ही उसे बंद कर दे.
कोल्ड स्टार्ट
कोल्ड स्टार्ट, किसी ऐप्लिकेशन के शुरू होने के बारे में बताता है. इसका मतलब है कि इस प्रोसेस के शुरू होने तक, सिस्टम की प्रोसेस, ऐप्लिकेशन की प्रोसेस बनाती है. कोल्ड स्टार्ट तब होता है, जब डिवाइस बूट होने के बाद पहली बार आपका ऐप्लिकेशन लॉन्च किया जाता है या जब सिस्टम ऐप्लिकेशन को बंद कर देता है.
इस तरह से शुरू होने पर, स्टार्टअप के समय को कम करना सबसे बड़ी चुनौती होती है, क्योंकि सिस्टम और ऐप्लिकेशन के पास लॉन्च की दूसरी स्थितियों की तुलना में ज़्यादा काम होता है.
कोल्ड स्टार्ट की शुरुआत में, सिस्टम को ये तीन काम करने होते हैं:
- ऐप्लिकेशन को लोड करें और लॉन्च करें.
- ऐप्लिकेशन लॉन्च होने के तुरंत बाद, उसकी शुरुआती विंडो को खाली दिखाएं.
- ऐप्लिकेशन की प्रोसेस बनाएं.
सिस्टम के ऐप्लिकेशन प्रोसेस बनाने के तुरंत बाद, ऐप्लिकेशन प्रोसेस इन चरणों के लिए ज़िम्मेदार होती है:
- ऐप्लिकेशन ऑब्जेक्ट बनाएं.
- मुख्य थ्रेड लॉन्च करें.
- मुख्य गतिविधि बनाएं.
- व्यू की संख्या बढ़ाना.
- स्क्रीन का लेआउट.
- शुरुआती ड्रॉ करें.
जब ऐप्लिकेशन प्रोसेस, पहली बार ड्रॉ करने की प्रोसेस पूरी कर लेती है, तो सिस्टम प्रोसेस, बैकग्राउंड में दिखने वाली विंडो को स्वैप कर देती है. इसके बाद, उसे मुख्य ऐक्टिविटी से बदल देती है. इस समय, उपयोगकर्ता ऐप्लिकेशन का इस्तेमाल शुरू कर सकता है.
पहली इमेज में दिखाया गया है कि सिस्टम और ऐप्लिकेशन की प्रोसेस एक-दूसरे के बीच कैसे काम करती हैं.
ऐप्लिकेशन और गतिविधि बनाते समय, परफ़ॉर्मेंस से जुड़ी समस्याएं आ सकती हैं.
ऐप्लिकेशन बनाना
जब आपका ऐप्लिकेशन लॉन्च होता है, तब शुरुआती खाली विंडो स्क्रीन पर तब तक दिखती है, जब तक सिस्टम पहली बार ऐप्लिकेशन को ड्रॉ नहीं कर लेता. इस समय, सिस्टम प्रोसेस आपके ऐप्लिकेशन की शुरुआती विंडो को स्वैप कर देती है. इससे उपयोगकर्ता को ऐप्लिकेशन के साथ इंटरैक्ट करने की अनुमति मिल जाती है.
अगर आपने अपने ऐप्लिकेशन में Application.onCreate() को बदल दिया है, तो सिस्टम आपके ऐप्लिकेशन ऑब्जेक्ट पर onCreate() तरीके को लागू करता है. इसके बाद, ऐप्लिकेशन मुख्य थ्रेड शुरू करता है. इसे यूज़र इंटरफ़ेस (यूआई) थ्रेड भी कहा जाता है. साथ ही, इसे आपकी मुख्य ऐक्टिविटी बनाने का काम सौंपता है.
इसके बाद, सिस्टम और ऐप्लिकेशन लेवल की प्रोसेस, ऐप्लिकेशन के लाइफ़साइकल के चरणों के हिसाब से आगे बढ़ती हैं.
गतिविधि बनाना
ऐप्लिकेशन की प्रोसेस से आपकी ऐक्टिविटी बनने के बाद, ऐक्टिविटी ये कार्रवाइयां करती है:
- वैल्यू सेट करता है.
- कंस्ट्रक्टर को कॉल करता है.
- यह कॉलबैक मैथड को कॉल करता है. जैसे,
Activity.onCreate(). यह ऐक्टिविटी की लाइफ़साइकल की मौजूदा स्थिति के हिसाब से सही होता है.
आम तौर पर, onCreate() तरीके का लोड होने में लगने वाले समय पर सबसे ज़्यादा असर पड़ता है. ऐसा इसलिए, क्योंकि यह सबसे ज़्यादा ओवरहेड के साथ काम करता है: व्यू लोड करना और बढ़ाना. साथ ही, गतिविधि को चलाने के लिए ज़रूरी ऑब्जेक्ट को शुरू करना.
वॉर्म स्टार्ट
वॉर्म स्टार्ट में, कोल्ड स्टार्ट के दौरान होने वाली कार्रवाइयों का सबसेट शामिल होता है. हालांकि, यह हॉट स्टार्ट की तुलना में ज़्यादा ओवरहेड दिखाता है. ऐसे कई संभावित स्टेट हैं जिन्हें वार्म स्टार्ट माना जा सकता है. जैसे, ये स्टेट:
जब उपयोगकर्ता आपके ऐप्लिकेशन से बाहर निकल जाता है, लेकिन फिर से उसे लॉन्च करता है. यह प्रोसेस जारी रह सकती है. हालांकि, ऐप्लिकेशन को
onCreate()को कॉल करके, गतिविधि को नए सिरे से बनाना होगा.सिस्टम, आपके ऐप्लिकेशन को मेमोरी से हटा देता है. इसके बाद, उपयोगकर्ता उसे फिर से लॉन्च करता है. प्रोसेस और गतिविधि को फिर से शुरू करना होगा. हालांकि, टास्क को सेव किए गए इंस्टेंस की स्थिति वाले बंडल से कुछ फ़ायदा मिल सकता है. यह बंडल,
onCreate()में पास किया जाता है.
हॉट स्टार्ट
आपके ऐप्लिकेशन के हॉट स्टार्ट में, कोल्ड स्टार्ट की तुलना में कम ओवरहेड होता है. हॉट स्टार्ट में, सिस्टम आपकी गतिविधि को फ़ोरग्राउंड में ले आता है. अगर आपके ऐप्लिकेशन की सभी गतिविधियां अब भी मेमोरी में मौजूद हैं, तो ऐप्लिकेशन को ऑब्जेक्ट के इनिशियलाइज़ेशन, लेआउट इन्फ़्लेशन, और रेंडरिंग को दोहराने से रोका जा सकता है.
हालांकि, अगर मेमोरी ट्रिमिंग इवेंट, जैसे कि onTrimMemory() के जवाब में कुछ मेमोरी हटा दी जाती है, तो इन ऑब्जेक्ट को हॉट स्टार्ट इवेंट के जवाब में फिर से बनाना होगा.
हॉट स्टार्ट में, स्क्रीन पर वही व्यवहार दिखता है जो कोल्ड स्टार्ट में दिखता है. सिस्टम प्रोसेस, ऐप्लिकेशन के गतिविधि को रेंडर करने तक खाली स्क्रीन दिखाती है.
Perfetto में ऐप्लिकेशन के शुरू होने की प्रोसेस की पहचान कैसे करें
ऐप्लिकेशन के शुरू होने में आने वाली समस्याओं को ठीक करने के लिए, यह जानना ज़रूरी है कि ऐप्लिकेशन के शुरू होने की प्रोसेस में क्या-क्या शामिल होता है. Perfetto में, ऐप्लिकेशन के स्टार्टअप फ़ेज़ की पूरी जानकारी देखने के लिए, यह तरीका अपनाएं:
Perfetto में, Android ऐप्लिकेशन के स्टार्टअप से जुड़ी डिराइव की गई मेट्रिक वाली लाइन ढूंढें. अगर आपको यह नहीं दिखता है, तो डिवाइस पर मौजूद सिस्टम ट्रेसिंग ऐप्लिकेशन का इस्तेमाल करके ट्रेस कैप्चर करने की कोशिश करें.
तीसरी इमेज.Perfetto में, Android ऐप्लिकेशन के स्टार्टअप से मिली मेट्रिक का स्लाइस. स्लाइस चुनने के लिए, उससे जुड़े स्लाइस पर क्लिक करें और m दबाएं. स्लाइस के चारों ओर ब्रैकेट दिखते हैं. इनसे पता चलता है कि स्लाइस को पूरा होने में कितना समय लगा. अवधि की जानकारी, मौजूदा चुनाव टैब में भी दिखती है.
Android ऐप्लिकेशन स्टार्टअप की लाइन को पिन करने के लिए, पिन आइकॉन पर क्लिक करें. यह आइकॉन तब दिखता है, जब लाइन पर पॉइंटर घुमाया जाता है.
उस ऐप्लिकेशन की लाइन तक स्क्रोल करें जिसके बारे में आपको जानकारी चाहिए. इसके बाद, लाइन को बड़ा करने के लिए पहले सेल पर क्लिक करें.
w दबाकर, मुख्य थ्रेड में ज़ूम इन करें. यह आम तौर पर सबसे ऊपर होता है. ज़ूम आउट करने, बाईं ओर जाने, और दाईं ओर जाने के लिए, s, a, d दबाएं.
चौथी इमेज.ऐप्लिकेशन के मुख्य थ्रेड के बगल में, Android ऐप्लिकेशन के स्टार्टअप से मिली मेट्रिक का स्लाइस. डिराइव की गई मेट्रिक के स्लाइस से, यह देखना आसान हो जाता है कि ऐप्लिकेशन के स्टार्टअप में क्या-क्या शामिल है. इससे आपको ज़्यादा जानकारी के साथ डीबग करने में मदद मिलती है.
स्टार्टअप की जांच करने और उन्हें बेहतर बनाने के लिए मेट्रिक का इस्तेमाल करना
स्टार्टअप टाइम की परफ़ॉर्मेंस का सही तरीके से पता लगाने के लिए, उन मेट्रिक को ट्रैक किया जा सकता है जिनसे यह पता चलता है कि आपके ऐप्लिकेशन को शुरू होने में कितना समय लगता है. Android आपको यह बताने के लिए कई तरीके उपलब्ध कराता है कि आपके ऐप्लिकेशन में कोई समस्या है. साथ ही, यह समस्या का पता लगाने में आपकी मदद करता है. Android की ज़रूरी जानकारी की मदद से, आपको किसी समस्या के होने की सूचना मिल सकती है. साथ ही, डाइग्नोस्टिक्स टूल की मदद से, समस्या का पता लगाया जा सकता है.
स्टार्टअप मेट्रिक का इस्तेमाल करने के फ़ायदे
Android, ऐप्लिकेशन के कोल्ड और वॉर्म स्टार्टअप को ऑप्टिमाइज़ करने के लिए, शुरुआती डिसप्ले में लगने वाला समय (टीटीआईडी) और पूरी तरह से डिसप्ले होने में लगने वाला समय (टीटीएफ़डी) मेट्रिक का इस्तेमाल करता है. Android Runtime (ART), इन मेट्रिक के डेटा का इस्तेमाल करता है. इससे, आने वाले समय में स्टार्टअप को ऑप्टिमाइज़ करने के लिए, कोड को पहले से कंपाइल करने में मदद मिलती है.
ऐप्लिकेशन के तेज़ी से शुरू होने पर, उपयोगकर्ता लंबे समय तक आपके ऐप्लिकेशन का इस्तेमाल करते हैं. इससे, ऐप्लिकेशन को तुरंत बंद करने, इंस्टेंस को फिर से शुरू करने या किसी दूसरे ऐप्लिकेशन पर जाने के मामलों में कमी आती है.
Android की ज़रूरी जानकारी
Android की ज़रूरी जानकारी वाली सुविधा, आपके ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाने में मदद कर सकती है. इसके लिए, यह सुविधा आपको Play Console पर सूचनाएं भेजती है. ये सूचनाएं तब भेजी जाती हैं, जब आपके ऐप्लिकेशन को शुरू होने में ज़्यादा समय लगता है.
Android की ज़रूरी जानकारी के मुताबिक, आपके ऐप्लिकेशन के शुरू होने में लगने वाला यह समय बहुत ज़्यादा है:
- कोल्ड स्टार्टअप में पांच सेकंड या उससे ज़्यादा समय लगता है.
- वॉर्म स्टार्टअप में दो सेकंड या उससे ज़्यादा समय लगता है.
- हॉट स्टार्टअप में 1.5 सेकंड या उससे ज़्यादा समय लगता है.
Android की ज़रूरी जानकारी में, ऐप्लिकेशन खुलने में लगने वाले समय (टीटीआईडी) मेट्रिक का इस्तेमाल किया जाता है. Google Play, Android की ज़रूरी जानकारी का डेटा कैसे इकट्ठा करता है, इस बारे में जानने के लिए Play Console का दस्तावेज़ देखें.
शुरुआती डिसप्ले में लगने वाला समय
ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) का पहला फ़्रेम दिखने में लगने वाले समय को, शुरुआती डिसप्ले में लगने वाला समय (टीटीआईडी) कहा जाता है. यह मेट्रिक, किसी ऐप्लिकेशन के पहले फ़्रेम को रेंडर करने में लगने वाले समय को मेज़र करती है. इसमें कोल्ड स्टार्ट के दौरान प्रोसेस शुरू होने, कोल्ड या वार्म स्टार्ट के दौरान गतिविधि बनाने, और पहला फ़्रेम दिखाने में लगने वाला समय शामिल है. अपने ऐप्लिकेशन का टीटीआईडी कम रखने से, उपयोगकर्ताओं को बेहतर अनुभव मिलता है. ऐसा इसलिए, क्योंकि इससे उपयोगकर्ताओं को आपका ऐप्लिकेशन तुरंत लॉन्च होता हुआ दिखता है. Android फ़्रेमवर्क, हर ऐप्लिकेशन के लिए टीटीआईडी अपने-आप रिपोर्ट करता है. ऐप्लिकेशन स्टार्टअप के लिए ऑप्टिमाइज़ करते समय, हमारा सुझाव है कि reportFullyDrawn लागू करें, ताकि आपको टीटीएफ़डी तक की जानकारी मिल सके.
टीटीआईडी को समय की वैल्यू के तौर पर मापा जाता है. यह वह कुल समय होता है जो इन इवेंट के क्रम में लगता है:
- प्रोसेस शुरू की जा रही है.
- ऑब्जेक्ट शुरू किए जा रहे हैं.
- गतिविधि बनाई जा रही है और उसे शुरू किया जा रहा है.
- लेआउट को बड़ा किया जा रहा है.
- ऐप्लिकेशन को पहली बार ड्रॉ करना.
TTID फिर से पाना
टीटीआईडी ढूंढने के लिए, Logcat कमांड-लाइन टूल में, Displayed वैल्यू वाली आउटपुट लाइन खोजें. यह वैल्यू टीटीआईडी होती है. यह नीचे दिए गए उदाहरण की तरह दिखती है. इस उदाहरण में टीटीआईडी 3s534ms है:
ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms
Android Studio में टीटीआईडी ढूंढने के लिए, फ़िल्टर ड्रॉप-डाउन से Logcat व्यू में फ़िल्टर बंद करें. इसके बाद, Displayed समय ढूंढें. इसे इमेज 5 में दिखाया गया है.
फ़िल्टर बंद करना ज़रूरी है, क्योंकि इस लॉग को सिस्टम सर्वर उपलब्ध कराता है, न कि ऐप्लिकेशन.
Displayed
वैल्यू.Logcat आउटपुट में मौजूद Displayed मेट्रिक, यह जानकारी नहीं देती कि सभी संसाधनों को लोड होने और दिखने में कितना समय लगा. यह उन संसाधनों को छोड़ देता है जिन्हें लेआउट फ़ाइल में रेफ़रंस नहीं किया गया है या जिन्हें ऐप्लिकेशन, ऑब्जेक्ट को शुरू करने के हिस्से के तौर पर बनाता है. इसमें इन संसाधनों को शामिल नहीं किया जाता, क्योंकि इन्हें लोड करना एक इनलाइन प्रोसेस है. साथ ही, यह ऐप्लिकेशन के शुरुआती डिसप्ले को ब्लॉक नहीं करता है.
कभी-कभी, Logcat के आउटपुट में मौजूद Displayed लाइन में, कुल समय के लिए एक अतिरिक्त फ़ील्ड होता है. उदाहरण के लिए:
ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)
इस मामले में, पहली बार मेज़रमेंट सिर्फ़ उस गतिविधि के लिए होता है जिसे सबसे पहले ड्रा किया जाता है. total को मापने की प्रोसेस, ऐप्लिकेशन प्रोसेस के शुरू होने पर शुरू होती है. इसमें ऐसी दूसरी गतिविधि भी शामिल हो सकती है जिसे पहले शुरू किया गया हो, लेकिन वह स्क्रीन पर कुछ भी नहीं दिखाती है. total समय का मेज़रमेंट सिर्फ़ तब दिखाया जाता है, जब किसी एक गतिविधि और शुरू होने में लगने वाले कुल समय के बीच अंतर होता है.
हमारा सुझाव है कि Android Studio में Logcat का इस्तेमाल करें. हालांकि, अगर Android Studio का इस्तेमाल नहीं किया जा रहा है, तो adb शेल ऐक्टिविटी मैनेजर कमांड का इस्तेमाल करके, अपने ऐप्लिकेशन को चलाकर भी टीटीआईडी को मेज़र किया जा सकता है. यहां एक उदाहरण दिया गया है:
adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN
Displayed मेट्रिक, Logcat के आउटपुट में पहले की तरह दिखती है. आपकी टर्मिनल विंडो में यह जानकारी दिखती है:
Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete
-c और -a आर्ग्युमेंट ज़रूरी नहीं हैं. इनकी मदद से, <category> और <action> तय किए जा सकते हैं.
पूरी तरह से दिखने में लगने वाला समय
टीटीएफ़डी (टाइम टू फ़ुल डिसप्ले) से पता चलता है कि किसी ऐप्लिकेशन को उपयोगकर्ता के लिए इंटरैक्टिव बनने में कितना समय लगता है. इसे ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) का पहला फ़्रेम दिखाने में लगने वाले समय के तौर पर रिपोर्ट किया जाता है. साथ ही, इसमें वह कॉन्टेंट भी शामिल होता है जो शुरुआती फ़्रेम दिखने के बाद एसिंक्रोनस तरीके से लोड होता है. आम तौर पर, यह नेटवर्क या डिस्क से लोड किया गया मुख्य कॉन्टेंट होता है, जैसा कि ऐप्लिकेशन ने बताया है. दूसरे शब्दों में, टीटीएफ़डी में टीटीआईडी के साथ-साथ, ऐप्लिकेशन के इस्तेमाल के लिए तैयार होने में लगने वाला समय भी शामिल होता है. अपने ऐप्लिकेशन के टीटीएफ़डी को कम रखने से, उपयोगकर्ता अनुभव को बेहतर बनाने में मदद मिलती है. इससे उपयोगकर्ता, आपके ऐप्लिकेशन के साथ तुरंत इंटरैक्ट कर पाते हैं.
सिस्टम, टीटीआईडी का पता तब लगाता है, जब Choreographer, गतिविधि के onDraw() तरीके को कॉल करता है. साथ ही, जब उसे पता चलता है कि वह इसे पहली बार कॉल कर रहा है.
हालांकि, सिस्टम को यह नहीं पता होता कि टीटीएफ़डी का पता कब लगाना है, क्योंकि हर ऐप्लिकेशन अलग-अलग तरीके से काम करता है. टीटीएफ़डी का पता लगाने के लिए, ऐप्लिकेशन को सिस्टम को यह सिग्नल देना होगा कि वह पूरी तरह से रेंडर हो गया है.
टीटीएफ़डी वापस पाना
टीटीएफ़डी का पता लगाने के लिए, ComponentActivity के reportFullyDrawn() तरीके को कॉल करके, पूरी तरह से ड्रॉ की गई स्थिति का सिग्नल दें. reportFullyDrawn तरीके से यह पता चलता है कि ऐप्लिकेशन पूरी तरह से रेंडर हो गया है और इस्तेमाल किया जा सकता है. टीटीएफ़डी, ऐप्लिकेशन लॉन्च करने का अनुरोध मिलने से लेकर reportFullyDrawn() को कॉल करने तक का समय होता है. अगर reportFullyDrawn() को कॉल नहीं किया जाता है, तो टीटीएफ़डी की कोई वैल्यू रिपोर्ट नहीं की जाती है.
टीटीएफ़डी को मेज़र करने के लिए, यूज़र इंटरफ़ेस (यूआई) और सभी डेटा को पूरी तरह से ड्रॉ करने के बाद, reportFullyDrawn() को कॉल करें. पहली गतिविधि की विंडो के पहली बार ड्रॉ होने और सिस्टम के मेज़र किए गए समय के हिसाब से दिखने से पहले, reportFullyDrawn() को कॉल न करें. ऐसा इसलिए, क्योंकि इसके बाद सिस्टम, सिस्टम के मेज़र किए गए समय की रिपोर्ट करता है. दूसरे शब्दों में, अगर सिस्टम के टीटीआईडी का पता लगाने से पहले reportFullyDrawn() को कॉल किया जाता है, तो सिस्टम टीटीआईडी और टीटीएफ़डी, दोनों को एक ही वैल्यू के तौर पर रिपोर्ट करता है. यह वैल्यू, टीटीआईडी की वैल्यू होती है.
reportFullyDrawn() का इस्तेमाल करने पर, Logcat में इस उदाहरण जैसा आउटपुट दिखता है. इसमें टीटीएफ़डी 1 सेकंड 54 मि॰से॰ है:
system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms
Logcat के आउटपुट में कभी-कभी total समय भी शामिल होता है. इसके बारे में पहली बार दिखने में लगने वाला समय लेख में बताया गया है.
अगर आपको लगता है कि आपकी वेबसाइट के डिसप्ले होने में ज़्यादा समय लग रहा है, तो स्टार्टअप प्रोसेस में आने वाली रुकावटों का पता लगाएं.
reportFullyDrawn() का इस्तेमाल करके, सामान्य मामलों में पूरी तरह से रेंडर होने की स्थिति के बारे में बताया जा सकता है. ऐसा तब करें, जब आपको पता हो कि पूरी तरह से रेंडर होने की स्थिति हासिल हो गई है. हालांकि, कुछ मामलों में बैकग्राउंड थ्रेड को पूरी तरह से रेंडर होने से पहले बैकग्राउंड में काम पूरा करना होता है. ऐसे में, आपको टीटीएफ़डी को ज़्यादा सटीक तरीके से मेज़र करने के लिए, reportFullyDrawn() को कुछ समय के लिए रोकना होगा. reportFullyDrawn() को कुछ समय के लिए रोकने का तरीका जानने के लिए, यहां दिया गया सेक्शन देखें.
स्टार्टअप के समय की सटीक जानकारी को बेहतर बनाना
अगर आपका ऐप्लिकेशन लेज़ी लोडिंग की सुविधा का इस्तेमाल कर रहा है और शुरुआती डिसप्ले में सभी संसाधन शामिल नहीं हैं, जैसे कि जब आपका ऐप्लिकेशन नेटवर्क से इमेज फ़ेच कर रहा हो, तो आपको reportFullyDrawn को तब तक कॉल नहीं करना चाहिए, जब तक आपका ऐप्लिकेशन इस्तेमाल करने लायक न हो जाए. इससे, सूची में डेटा भरने की प्रोसेस को बेंचमार्क टाइमिंग में शामिल किया जा सकता है.
उदाहरण के लिए, अगर यूज़र इंटरफ़ेस (यूआई) में डाइनैमिक सूची है, जैसे कि RecyclerView या लेज़ी लिस्ट, तो हो सकता है कि लिस्ट को बैकग्राउंड टास्क से भरा गया हो. यह टास्क, लिस्ट के पहली बार दिखने के बाद पूरा होता है. इसलिए, यूज़र इंटरफ़ेस (यूआई) को पूरी तरह से दिखने के तौर पर मार्क करने के बाद पूरा होता है.
ऐसे मामलों में, सूची में शामिल लोगों की संख्या को बेंचमार्किंग में शामिल नहीं किया जाता.
लिस्ट में शामिल लोगों की जानकारी को अपने बेंचमार्क टाइमिंग में शामिल करने के लिए, getFullyDrawnReporter() का इस्तेमाल करके FullyDrawnReporter पाएं. इसके बाद, अपने ऐप्लिकेशन कोड में जाकर, इसमें एक रिपोर्टर जोड़ें. बैकग्राउंड टास्क के पूरा होने के बाद, रिपोर्टर को रिलीज़ करें.
सभी जोड़े गए रिपोर्टर के रिलीज़ होने तक, FullyDrawnReporter, reportFullyDrawn() तरीके को कॉल नहीं करता. बैकग्राउंड प्रोसेस पूरी होने तक रिपोर्टर को जोड़ने पर, समय में वह समय भी शामिल होता है जो स्टार्टअप के समय के डेटा में सूची को भरने में लगता है. इससे उपयोगकर्ता के लिए ऐप्लिकेशन के व्यवहार में कोई बदलाव नहीं होता. हालांकि, इससे टाइमिंग स्टार्टअप डेटा में, सूची को भरने में लगने वाला समय शामिल किया जा सकता है. reportFullyDrawn() को तब तक कॉल नहीं किया जाता, जब तक सभी टास्क पूरे नहीं हो जाते. भले ही, टास्क किसी भी क्रम में पूरे हों.
यहां दिए गए उदाहरण में, एक साथ कई बैकग्राउंड टास्क चलाने का तरीका बताया गया है. इसमें हर टास्क अपना रिपोर्टर रजिस्टर करता है:
Kotlin
class MainActivity : ComponentActivity() {
sealed interface ActivityState {
data object LOADING : ActivityState
data object LOADED : ActivityState
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var activityState by remember {
mutableStateOf(ActivityState.LOADING as ActivityState)
}
fullyDrawnReporter.addOnReportDrawnListener {
activityState = ActivityState.LOADED
}
ReportFullyDrawnTheme {
when(activityState) {
is ActivityState.LOADING -> {
// Display the loading UI.
}
is ActivityState.LOADED -> {
// Display the full UI.
}
}
}
SideEffect {
fullyDrawnReporter.addReporter()
lifecycleScope.launch(Dispatchers.IO) {
// Perform the background operation.
fullyDrawnReporter.removeReporter()
}
fullyDrawnReporter.addReporter()
lifecycleScope.launch(Dispatchers.IO) {
// Perform the background operation.
fullyDrawnReporter.removeReporter()
}
}
}
}
}
Java
public class MainActivity extends ComponentActivity {
private FullyDrawnReporter fullyDrawnReporter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fullyDrawnReporter = getFullyDrawnReporter();
fullyDrawnReporter.addOnReportDrawnListener(() -> {
// Trigger the UI update.
return Unit.INSTANCE;
});
new Thread(new Runnable() {
@Override
public void run() {
fullyDrawnReporter.addReporter();
// Do the background work.
fullyDrawnReporter.removeReporter();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
fullyDrawnReporter.addReporter();
// Do the background work.
fullyDrawnReporter.removeReporter();
}
}).start();
}
}
अगर आपका ऐप्लिकेशन Jetpack Compose का इस्तेमाल करता है, तो पूरी तरह से ड्रॉ की गई स्थिति को दिखाने के लिए, इन एपीआई का इस्तेमाल किया जा सकता है:
ReportDrawn: इससे पता चलता है कि आपका कंपोज़ेबल, तुरंत इंटरैक्ट करने के लिए तैयार है.ReportDrawnWhen: यह एक प्रेडिकेट लेता है, जैसे किlist.count > 0. इससे यह पता चलता है कि आपका कंपोज़ेबल इंटरैक्शन के लिए कब तैयार है.ReportDrawnAfter: यह एक ऐसा तरीका है जो यह दिखाता है कि आपका कंपोज़ेबल, इंटरैक्शन के लिए तैयार है.
बॉटलनैक की पहचान करना
परफ़ॉर्मेंस से जुड़ी समस्याओं का पता लगाने के लिए, Android Studio CPU Profiler का इस्तेमाल किया जा सकता है. ज़्यादा जानकारी के लिए, सीपीयू प्रोफ़ाइलर की मदद से सीपीयू की गतिविधि की जांच करना लेख पढ़ें.
अपने ऐप्लिकेशन और गतिविधियों के onCreate() तरीकों में इनलाइन ट्रेसिंग की मदद से, संभावित समस्याओं के बारे में भी जानकारी पाई जा सकती है. इनलाइन ट्रेसिंग के बारे में जानने के लिए, Trace फ़ंक्शन और सिस्टम ट्रेसिंग की खास जानकारी से जुड़ा दस्तावेज़ देखें.
सामान्य समस्याएं हल करना
इस सेक्शन में, उन समस्याओं के बारे में बताया गया है जो अक्सर ऐप्लिकेशन के स्टार्टअप की परफ़ॉर्मेंस पर असर डालती हैं. ये समस्याएं मुख्य रूप से ऐप्लिकेशन और गतिविधि ऑब्जेक्ट को शुरू करने के साथ-साथ स्क्रीन लोड करने से जुड़ी होती हैं.
ऐप्लिकेशन को शुरू करने में ज़्यादा समय लगना
Application ऑब्जेक्ट को शुरू करते समय, अगर आपका कोड उसे बदल देता है और ज़्यादा काम करता है या जटिल लॉजिक लागू करता है, तो लॉन्च परफ़ॉर्मेंस पर असर पड़ सकता है. अगर आपकी Application सबक्लास, स्टार्टअप के दौरान ऐसे इनिशियलाइज़ेशन करती हैं जिनकी अभी ज़रूरत नहीं है, तो आपके ऐप्लिकेशन को शुरू होने में समय लग सकता है.
कुछ इनिशियलाइज़ेशन पूरी तरह से गैर-ज़रूरी हो सकते हैं. जैसे, जब ऐप्लिकेशन को किसी इंटेंट के जवाब में शुरू किया जाता है, तब मुख्य गतिविधि के लिए स्थिति की जानकारी को इनिशियलाइज़ करना. किसी इंटेंट के साथ, ऐप्लिकेशन पहले से शुरू किए गए स्टेट डेटा के सिर्फ़ सबसेट का इस्तेमाल करता है.
ऐप्लिकेशन को शुरू करने के दौरान आने वाली अन्य समस्याओं में, गार्बेज कलेक्शन इवेंट शामिल हैं. ये इवेंट, ऐप्लिकेशन के परफ़ॉर्मेंस पर काफ़ी असर डालते हैं या इनकी संख्या बहुत ज़्यादा होती है. इसके अलावा, डिस्क I/O की प्रोसेस, ऐप्लिकेशन को शुरू करने की प्रोसेस के साथ-साथ चलती है. इससे ऐप्लिकेशन को शुरू करने की प्रोसेस में और रुकावट आती है. गार्बेज कलेक्शन, खास तौर पर Dalvik रनटाइम के लिए ज़रूरी है. Android रनटाइम (एआरटी), गार्बेज कलेक्शन को एक साथ करता है. इससे इस ऑपरेशन का असर कम हो जाता है.
समस्या का पता लगाना
समस्या का पता लगाने के लिए, मेथड ट्रेसिंग या इनलाइन ट्रेसिंग का इस्तेमाल किया जा सकता है.
मेथड ट्रेसिंग
सीपीयू प्रोफ़ाइलर चलाने से पता चलता है कि callApplicationOnCreate() तरीका, आखिर में आपके com.example.customApplication.onCreate तरीके को कॉल करता है. अगर टूल से पता चलता है कि इन तरीकों को पूरा होने में ज़्यादा समय लग रहा है, तो यह देखने के लिए और एक्सप्लोर करें कि वहां क्या काम हो रहा है.
इनलाइन ट्रेसिंग
इनलाइन ट्रेसिंग का इस्तेमाल करके, गड़बड़ी की वजह का पता लगाया जा सकता है. जैसे:
- आपके ऐप्लिकेशन का शुरुआती
onCreate()फ़ंक्शन. - आपके ऐप्लिकेशन के शुरू किए गए कोई भी ग्लोबल सिंगलटन ऑब्जेक्ट.
- डिस्क I/O, डिसीरियलाइज़ेशन या टाइट लूप से जुड़ी कोई भी समस्या जो परफ़ॉर्मेंस में रुकावट आने के दौरान हो रही हो.
समस्या को हल करने के तरीके
चाहे समस्या गैर-ज़रूरी इनिशियलाइज़ेशन की वजह से हो या डिस्क I/O की वजह से, इसका समाधान लेज़ी इनिशियलाइज़ेशन है. दूसरे शब्दों में कहें, तो सिर्फ़ उन ऑब्जेक्ट को शुरू करें जिनकी तुरंत ज़रूरत है. ग्लोबल स्टैटिक ऑब्जेक्ट बनाने के बजाय, सिंगलटन पैटर्न पर जाएं. इसमें ऐप्लिकेशन, ऑब्जेक्ट को सिर्फ़ पहली बार शुरू करता है, जब उसे उनकी ज़रूरत होती है.
इसके अलावा, Hilt जैसे डिपेंडेंसी इंजेक्शन फ़्रेमवर्क का इस्तेमाल करें. यह फ़्रेमवर्क, ऑब्जेक्ट और डिपेंडेंसी तब बनाता है, जब उन्हें पहली बार इंजेक्ट किया जाता है.
अगर आपका ऐप्लिकेशन, स्टार्टअप के समय ऐप्लिकेशन कॉम्पोनेंट को शुरू करने के लिए कॉन्टेंट प्रोवाइडर का इस्तेमाल करता है, तो इसके बजाय ऐप्लिकेशन स्टार्टअप लाइब्रेरी का इस्तेमाल करें.
ज़्यादा मेहनत वाली गतिविधि शुरू की जा रही है
गतिविधि बनाने में अक्सर बहुत ज़्यादा समय लगता है. अक्सर, परफ़ॉर्मेंस को बेहतर बनाने के लिए, इस काम को ऑप्टिमाइज़ करने के अवसर मिलते हैं. इस तरह की सामान्य समस्याएं ये हैं:
- बड़े या जटिल लेआउट को बड़ा करना.
- डिस्क या नेटवर्क I/O पर स्क्रीन ड्रॉइंग को ब्लॉक करना.
- बिटमैप लोड और डिकोड किए जा रहे हैं.
VectorDrawableऑब्जेक्ट को रास्टर किया जा रहा है.- गतिविधि के अन्य सबसिस्टम को शुरू करना.
समस्या का पता लगाना
इस मामले में भी, मेथड ट्रेसिंग और इनलाइन ट्रेसिंग, दोनों का इस्तेमाल किया जा सकता है.
मेथड ट्रेसिंग
सीपीयू प्रोफ़ाइलर का इस्तेमाल करते समय, अपने ऐप्लिकेशन के Application सबक्लास कंस्ट्रक्टर और com.example.customApplication.onCreate() तरीकों पर ध्यान दें.
अगर टूल से पता चलता है कि इन तरीकों को पूरा होने में ज़्यादा समय लग रहा है, तो यह देखने के लिए और एक्सप्लोर करें कि वहां क्या काम हो रहा है.
इनलाइन ट्रेसिंग
इनलाइन ट्रेसिंग का इस्तेमाल करके, गड़बड़ी की वजह का पता लगाया जा सकता है. जैसे:
- आपके ऐप्लिकेशन का शुरुआती
onCreate()फ़ंक्शन. - यह किसी भी ग्लोबल सिंगलटन ऑब्जेक्ट को शुरू करता है.
- डिस्क I/O, डिसीरियलाइज़ेशन या टाइट लूप से जुड़ी कोई भी समस्या जो परफ़ॉर्मेंस में रुकावट आने के दौरान हो रही हो.
समस्या को हल करने के तरीके
कई संभावित समस्याएं हो सकती हैं. हालांकि, दो सामान्य समस्याएं और उनके समाधान यहां दिए गए हैं:
- व्यू हैरारकी जितनी बड़ी होगी, ऐप्लिकेशन को उसे बढ़ाने में उतना ही ज़्यादा समय लगेगा. इस समस्या को हल करने के लिए, ये दो तरीके अपनाए जा सकते हैं:
- ज़रूरत से ज़्यादा या नेस्ट किए गए लेआउट कम करके, व्यू हैरारकी को फ़्लैट करें.
- लॉन्च के दौरान, यूज़र इंटरफ़ेस (यूआई) के उन हिस्सों को बड़ा न करें जिन्हें दिखाने की ज़रूरत नहीं है.
इसके बजाय,
ViewStubऑब्जेक्ट का इस्तेमाल करें. यह सब-हायरार्की के लिए प्लेसहोल्डर के तौर पर काम करता है. ऐप्लिकेशन, इसे ज़्यादा सही समय पर बड़ा कर सकता है.
- सभी संसाधनों को मुख्य थ्रेड पर शुरू करने से भी, ऐप्लिकेशन के खुलने में ज़्यादा समय लग सकता है. इस समस्या को हल करने के लिए, यह तरीका अपनाएं:
- सभी संसाधन शुरू करने की प्रोसेस को दूसरी थ्रेड पर ले जाएं, ताकि ऐप्लिकेशन इसे ज़रूरत के हिसाब से कर सके.
- ऐप्लिकेशन को अपने व्यू लोड करने और दिखाने दें. इसके बाद, बिटमैप और अन्य संसाधनों पर निर्भर विज़ुअल प्रॉपर्टी अपडेट करें.
पसंद के मुताबिक स्प्लैश स्क्रीन
अगर आपने Android 11 (एपीआई लेवल 30) या इससे पहले के वर्शन में कस्टम स्प्लैश स्क्रीन लागू करने के लिए, इनमें से किसी एक तरीके का इस्तेमाल किया था, तो आपको स्टार्टअप के दौरान ज़्यादा समय लग सकता है:
windowDisablePreviewथीम एट्रिब्यूट का इस्तेमाल करके, लॉन्च के दौरान सिस्टम की ओर से बनाई गई शुरुआती खाली स्क्रीन को बंद किया जा सकता है.- खास तौर पर बनाए गए
Activityका इस्तेमाल करना.
Android 12 से, SplashScreen एपीआई पर माइग्रेट करना ज़रूरी है.
इस एपीआई की मदद से, ऐप्लिकेशन को तेज़ी से शुरू किया जा सकता है. साथ ही, स्प्लैश स्क्रीन में इन तरीकों से बदलाव किया जा सकता है:
- स्प्लैश स्क्रीन का लुक बदलने के लिए, कोई थीम सेट करें.
- यह कंट्रोल करें कि स्प्लैश स्क्रीन पर
windowSplashScreenAnimationDurationकितनी देर तक दिखे. - स्प्लैश स्क्रीन के ऐनिमेशन को पसंद के मुताबिक बनाएं. साथ ही, स्प्लैश स्क्रीन को खारिज करने के लिए ऐनिमेशन को आसानी से मैनेज करें.
इसके अलावा, कंपैट लाइब्रेरी SplashScreen एपीआई को पुराने सिस्टम के साथ काम करने की सुविधा के लिए बैकपोर्ट करती है. साथ ही, यह सभी Android वर्शन पर स्प्लैश स्क्रीन को एक जैसा दिखाने और उसका अनुभव एक जैसा रखने के लिए भी ऐसा करती है.
ज़्यादा जानकारी के लिए, स्प्लैश स्क्रीन माइग्रेशन गाइड देखें.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक का टेक्स्ट दिखता है
- धीमी रेंडरिंग
- Macrobenchmark मेट्रिक कैप्चर करना
- बेसलाइन प्रोफ़ाइलें बनाना{:#creating-profile-rules}