ऐप्लिकेशन स्टार्टअप समय

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

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

ऐप्लिकेशन के शुरू होने की अलग-अलग स्थितियों के बारे में जानकारी

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

हमारा सुझाव है कि आप हमेशा कोल्ड स्टार्ट के अनुमान के आधार पर ऑप्टिमाइज़ करें. ऐसा करने से, वॉर्म और हॉट स्टार्ट की परफ़ॉर्मेंस भी बेहतर हो सकती है.

ऐप्लिकेशन को तेज़ी से चालू करने के लिए ऑप्टिमाइज़ करने के लिए, यह समझना ज़रूरी है कि सिस्टम और ऐप्लिकेशन लेवल पर क्या हो रहा है. साथ ही, यह भी समझना ज़रूरी है कि ये दोनों लेवल, इन सभी स्थितियों में कैसे इंटरैक्ट करते हैं.

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

कोल्ड स्टार्ट

कोल्ड स्टार्ट, किसी ऐप्लिकेशन के शुरू करने के बारे में बताता है. इसका मतलब है कि इस स्टार्ट से पहले, सिस्टम की प्रोसेस ऐप्लिकेशन की प्रोसेस बनाती है. कोल्ड स्टार्ट तब होता है, जब डिवाइस बूट होने के बाद पहली बार आपका ऐप्लिकेशन लॉन्च किया जाता है या जब सिस्टम ऐप्लिकेशन को बंद कर देता है.

इस तरह से शुरू होने पर, स्टार्टअप के समय को कम करना सबसे बड़ी चुनौती होती है, क्योंकि सिस्टम और ऐप्लिकेशन के पास लॉन्च की दूसरी स्थितियों की तुलना में ज़्यादा काम होता है.

कोल्ड स्टार्ट की शुरुआत में, सिस्टम को ये तीन काम करने होते हैं:

  1. ऐप्लिकेशन को लोड करें और लॉन्च करें.
  2. ऐप्लिकेशन लॉन्च होने के तुरंत बाद, ऐप्लिकेशन के लिए खाली शुरुआती विंडो दिखाएं.
  3. ऐप्लिकेशन की प्रोसेस बनाएं.

सिस्टम के ऐप्लिकेशन प्रोसेस बनाने के तुरंत बाद, ऐप्लिकेशन प्रोसेस इन चरणों के लिए ज़िम्मेदार होती है:

  1. ऐप्लिकेशन ऑब्जेक्ट बनाएं.
  2. मुख्य थ्रेड लॉन्च करें.
  3. मुख्य गतिविधि बनाएं.
  4. यूज़र इंटरफ़ेस (यूआई) शुरू करें.
  5. स्क्रीन पर यूज़र इंटरफ़ेस (यूआई) ड्रॉ करें.

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

Compose में लेआउट के फ़ेज़ के बारे में ज़्यादा जानने के लिए, Jetpack Compose के फ़ेज़ देखें.

ऐप्लिकेशन और होस्ट ऐक्टिविटी बनाते समय, परफ़ॉर्मेंस से जुड़ी समस्याएं आ सकती हैं.

ऐप्लिकेशन बनाना

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

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

इसके बाद, सिस्टम और ऐप्लिकेशन लेवल की प्रोसेस, ऐप्लिकेशन के लाइफ़साइकल के चरणों के हिसाब से आगे बढ़ती हैं.

गतिविधि बनाना

ऐप्लिकेशन प्रोसेस के ज़रिए आपकी गतिविधि बनाने के बाद, गतिविधि ये कार्रवाइयां करती है:

  1. वैल्यू सेट करता है.
  2. कंस्ट्रक्टर को कॉल करता है.
  3. यह कॉलबैक मैथड को कॉल करता है. जैसे, Activity.onCreate. यह ऐक्टिविटी की लाइफ़साइकल की मौजूदा स्थिति के हिसाब से सही होता है.

आम तौर पर, onCreate तरीके का इस्तेमाल करने से, कॉन्टेंट लोड होने में लगने वाले समय पर सबसे ज़्यादा असर पड़ता है. Jetpack Compose ऐप्लिकेशन में, onCreate तरीके का ओवरहेड अक्सर शुरुआती कंपोज़िशन से आता है. ऐसा तब होता है, जब आपका ऐप्लिकेशन setContent को कॉल करता है और आपके टॉप-लेवल कंपोज़ेबल को शुरू करता है. डीप या जटिल यूज़र इंटरफ़ेस (यूआई) हैरारकी या मुख्य थ्रेड पर भारी कैलकुलेशन करने वाले कंपोज़ेबल की वजह से, कंपोज़िशन में लगने वाला समय बढ़ सकता है.

वॉर्म स्टार्ट

वॉर्म स्टार्ट में, कोल्ड स्टार्ट के दौरान होने वाली कार्रवाइयों का सबसेट शामिल होता है. हालांकि, इसमें हॉट स्टार्ट की तुलना में ज़्यादा समय लगता है. ऐसे कई संभावित स्टेट हैं जिन्हें वार्म स्टार्ट माना जा सकता है. जैसे, ये स्टेट:

  • जब उपयोगकर्ता आपके ऐप्लिकेशन से बाहर निकल जाता है, लेकिन फिर से उसे लॉन्च करता है. यह प्रोसेस जारी रह सकती है. हालांकि, ऐप्लिकेशन को onCreate को कॉल करके, गतिविधि को नए सिरे से बनाना होगा.

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

हॉट स्टार्ट

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

हालांकि, अगर मेमोरी को कम करने वाले इवेंट, जैसे कि onTrimMemory के जवाब में कुछ मेमोरी खाली की जाती है, तो इन ऑब्जेक्ट को हॉट स्टार्ट इवेंट के जवाब में फिर से बनाना होगा.

हॉट स्टार्ट में, स्क्रीन पर वही व्यवहार दिखता है जो कोल्ड स्टार्ट में दिखता है. सिस्टम प्रोसेस, ऐप्लिकेशन के गतिविधि को रेंडर करने की प्रोसेस पूरी होने तक खाली स्क्रीन दिखाती है.

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

Perfetto में ऐप्लिकेशन के शुरू होने की प्रोसेस की पहचान कैसे करें

ऐप्लिकेशन के शुरू होने में आने वाली समस्याओं को डीबग करने के लिए, यह जानना ज़रूरी है कि ऐप्लिकेशन के शुरू होने की प्रोसेस में क्या-क्या शामिल है. Perfetto में, ऐप्लिकेशन के स्टार्टअप फ़ेज़ की पूरी जानकारी देखने के लिए, यह तरीका अपनाएं:

  1. Perfetto में, Android ऐप्लिकेशन के स्टार्टअप से जुड़ी डिराइव की गई मेट्रिक वाली लाइन ढूंढें. अगर आपको यह विकल्प नहीं दिखता है, तो डिवाइस पर मौजूद सिस्टम ट्रेसिंग ऐप्लिकेशन का इस्तेमाल करके ट्रेस कैप्चर करें.

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

  3. Android ऐप्लिकेशन स्टार्टअप की लाइन को पिन करने के लिए, पिन आइकॉन पर क्लिक करें. यह आइकॉन तब दिखता है, जब लाइन पर पॉइंटर को घुमाया जाता है.

  4. उस ऐप्लिकेशन की लाइन पर जाएं जिसके बारे में आपको जानकारी चाहिए. इसके बाद, लाइन को बड़ा करने के लिए पहले सेल पर क्लिक करें.

  5. w दबाकर, मुख्य थ्रेड में ज़ूम इन करें. यह आम तौर पर सबसे ऊपर होता है (ज़ूम आउट करने, बाईं ओर जाने, और दाईं ओर जाने के लिए, s, a, d दबाएं).

    तीसरी इमेज. Android ऐप्लिकेशन के शुरू होने में लगने वाले समय की डिराइव की गई मेट्रिक का स्लाइस, ऐप्लिकेशन के मुख्य थ्रेड के बगल में दिखता है.
  6. डिराइव की गई मेट्रिक के स्लाइस से, यह देखना आसान हो जाता है कि ऐप्लिकेशन के स्टार्टअप में क्या-क्या शामिल है. इससे आपको ज़्यादा जानकारी के साथ डीबग करने में मदद मिलती है.

Jetpack Compose ऐप्लिकेशन का विश्लेषण करते समय, कंपोज़िशन ट्रेसिंग का इस्तेमाल करके, अपने यूज़र इंटरफ़ेस की परफ़ॉर्मेंस के बारे में ज़्यादा जानकारी देखी जा सकती है. मुख्य थ्रेड में मौजूद उन ट्रेस सेक्शन पर खास ध्यान दें जो Choreographer#doFrame से शुरू होते हैं. Compose:recompose, Compose:layout, और Compose:draw जैसे स्लाइस ढूंढें. इनसे पता चलता है कि आपका ऐप्लिकेशन, कंपोज़ करने, मेज़र करने, प्लेस करने, और खास कॉम्पोनेंट बनाने में कितना समय लेता है.

स्टार्टअप की जांच करने और उन्हें बेहतर बनाने के लिए मेट्रिक का इस्तेमाल करना

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

स्टार्टअप मेट्रिक का इस्तेमाल करने के फ़ायदे

Android, ऐप्लिकेशन के कोल्ड और वार्म स्टार्टअप को ऑप्टिमाइज़ करने के लिए, शुरुआती डिसप्ले में लगने वाला समय (टीटीआईडी) और पूरी तरह से डिसप्ले होने में लगने वाला समय (टीटीएफ़डी) मेट्रिक का इस्तेमाल करता है. Android Runtime (ART), इन मेट्रिक के डेटा का इस्तेमाल करता है. इससे, आने वाले समय में स्टार्टअप को ऑप्टिमाइज़ करने के लिए, कोड को पहले से कंपाइल किया जा सकता है.

ऐप्लिकेशन के तेज़ी से शुरू होने पर, उपयोगकर्ता का इंटरैक्शन उससे ज़्यादा समय तक बना रहता है. इससे, ऐप्लिकेशन को तुरंत बंद करने, इंस्टेंस को फिर से शुरू करने या किसी दूसरे ऐप्लिकेशन पर जाने के मामलों में कमी आती है.

शुरुआती डिसप्ले में लगने वाला समय

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

टीटीआईडी को समय की वैल्यू के तौर पर मापा जाता है. यह वह कुल समय होता है जो इन इवेंट के क्रम में लगता है:

  • प्रोसेस शुरू की जा रही है.
  • ऑब्जेक्ट शुरू किए जा रहे हैं.
  • होस्ट की गतिविधि बनाना और उसे शुरू करना.
  • यूज़र इंटरफ़ेस (यूआई) शुरू किया जा रहा है.
  • ऐप्लिकेशन को पहली बार ड्रॉ करना.

टीटीआईडी वापस पाना

टीटीआईडी ढूंढने के लिए, Logcat कमांड-लाइन टूल में, Displayed वैल्यू वाली आउटपुट लाइन खोजें. यह वैल्यू, टीटीआईडी होती है. यह इस उदाहरण की तरह दिखती है. इस उदाहरण में टीटीआईडी 3s534ms है:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

Android Studio में टीटीआईडी ढूंढने के लिए, ड्रॉप-डाउन फ़िल्टर मेन्यू से Logcat व्यू में फ़िल्टर बंद करें. इसके बाद, Displayed समय ढूंढें. इसे चौथे फ़िगर में दिखाया गया है. फ़िल्टर बंद करना ज़रूरी है, क्योंकि यह लॉग सिस्टम सर्वर देता है, न कि ऐप्लिकेशन.

चौथी इमेज. Logcat में, बंद किए गए फ़िल्टर और Displayed वैल्यू.

Logcat आउटपुट में मौजूद Displayed मेट्रिक, यह जानकारी नहीं देती कि सभी संसाधन लोड होने और दिखने में कितना समय लगा. यह उन रिसॉर्स को छोड़ देता है जिन्हें शुरुआती कंपोज़िशन में रेफ़रंस नहीं किया गया है. जैसे, एसिंक्रोनस तरीके से लोड किया गया डेटा या इमेज. इसके अलावा, यह उन रिसॉर्स को भी छोड़ देता है जिन्हें ऐप्लिकेशन, ऑब्जेक्ट के इनिशियलाइज़ेशन के हिस्से के तौर पर बनाता है. यह इन संसाधनों को शामिल नहीं करता, क्योंकि इन्हें लोड करना एक इनलाइन प्रोसेस है. साथ ही, यह ऐप्लिकेशन के शुरुआती डिसप्ले को ब्लॉक नहीं करता. संसाधनों के बारे में ज़्यादा जानने के लिए, Compose में संसाधन लेख पढ़ें.

कभी-कभी 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> तय किए जा सकते हैं.

पूरी तरह से दिखने में लगने वाला समय

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

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

टीटीएफ़डी वापस पाना

टीटीएफ़डी का पता लगाने के लिए, 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 को तब तक कॉल नहीं करना चाहिए, जब तक आपका ऐप्लिकेशन इस्तेमाल करने लायक न हो जाए. इससे, सूची में शामिल किए गए लोगों की जानकारी को बेंचमार्क टाइमिंग के हिस्से के तौर पर शामिल किया जा सकता है.

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

लिस्ट में शामिल लोगों की जानकारी को अपने बेंचमार्क टाइमिंग में शामिल करने के लिए, fullyDrawnReporter का इस्तेमाल करके FullyDrawnReporter पाएं. इसके बाद, अपने ऐप्लिकेशन कोड में जाकर, इसमें एक रिपोर्टर जोड़ें. बैकग्राउंड टास्क के पूरा होने के बाद, रिपोर्टर को रिलीज़ करें.

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

अगर आपका ऐप्लिकेशन Jetpack Compose का इस्तेमाल करता है, तो पूरी तरह से ड्रॉ की गई स्थिति को दिखाने के लिए, इन एपीआई का इस्तेमाल किया जा सकता है:

  • ReportDrawn: इससे पता चलता है कि आपका कंपोज़ेबल, तुरंत इंटरैक्ट करने के लिए तैयार है.
  • ReportDrawnWhen: यह एक प्रेडिकेट लेता है, जैसे कि list.count > 0. इससे यह पता चलता है कि आपका कंपोज़ेबल, इंटरैक्शन के लिए कब तैयार है.
  • ReportDrawnAfter: यह एक ऐसा तरीका है जो यह दिखाता है कि आपका कंपोज़ेबल, इंटरैक्शन के लिए तैयार है.

यहां दिए गए उदाहरण में, एक साथ कई बैकग्राउंड टास्क चलाने का तरीका बताया गया है. इसमें हर टास्क अपना रिपोर्टर रजिस्टर करता है:

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()
                }
            }
        }
    }
}
अवरोधों की पहचान करना

परफ़ॉर्मेंस से जुड़ी समस्याओं का पता लगाने के लिए, 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, डिसीरियलाइज़ेशन या टाइट लूप से जुड़ी कोई भी समस्या जो परफ़ॉर्मेंस में रुकावट के दौरान हो रही हो.

समस्या को हल करने के तरीके

कई संभावित समस्याएं हो सकती हैं. हालांकि, दो सामान्य समस्याएं और उनके समाधान यहां दिए गए हैं:

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

रीकंपोज़िशन के बारे में ज़्यादा जानने के लिए, रीकंपोज़िशन और रीकंपोज़िशन की संख्या पाना लेख पढ़ें.

पसंद के मुताबिक स्प्लैश स्क्रीन

अगर आपने Android 11 (एपीआई लेवल 30) या इससे पहले के वर्शन में कस्टम स्प्लैश स्क्रीन लागू करने के लिए, इनमें से किसी एक तरीके का इस्तेमाल किया था, तो आपको स्टार्टअप के दौरान ज़्यादा समय लग सकता है:

  • windowDisablePreview थीम एट्रिब्यूट का इस्तेमाल करके, लॉन्च के दौरान सिस्टम की ओर से बनाई गई शुरुआती खाली स्क्रीन को बंद किया जा सकता है.
  • खास तौर पर बनाए गए Activity का इस्तेमाल करना.

Android 12 से, SplashScreen एपीआई पर माइग्रेट करना ज़रूरी है. इस एपीआई की मदद से, ऐप्लिकेशन को तेज़ी से शुरू किया जा सकता है. साथ ही, स्प्लैश स्क्रीन में इन तरीकों से बदलाव किया जा सकता है:

इसके अलावा, कंपैट लाइब्रेरी SplashScreen एपीआई को बैकपोर्ट करती है, ताकि पुराने सिस्टम के साथ काम करने की सुविधा चालू की जा सके. साथ ही, सभी Android वर्शन पर स्प्लैश स्क्रीन का लुक और फ़ील एक जैसा हो.

ज़्यादा जानकारी के लिए, स्प्लैश स्क्रीन माइग्रेशन गाइड देखें.