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

उपयोगकर्ता चाहते हैं कि ऐप्लिकेशन तेज़ी से लोड हों और रिस्पॉन्सिव हों. अगर कोई ऐप्लिकेशन शुरू होने में ज़्यादा समय लेता है, तो वह उपयोगकर्ताओं की उम्मीदों पर खरा नहीं उतरता और उन्हें निराश कर सकता है. इस तरह के खराब अनुभव की वजह से, उपयोगकर्ता 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 रनटाइम (एआरटी), इन मेट्रिक के डेटा का इस्तेमाल करके, कोड को पहले से कंपाइल करता है. इससे, आने वाले समय में ऐप्लिकेशन के स्टार्टअप को ऑप्टिमाइज़ करने में मदद मिलती है.

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

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

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

टीटीआईडी को समय की वैल्यू के तौर पर मेज़र किया जाता है. यह वैल्यू, बीते हुए कुल समय को दिखाती है. इसमें इवेंट का यह क्रम शामिल होता है:

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

टीटीआईडी की जानकारी पाना

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

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

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

चौथी इमेज. 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 के सीपीयू प्रोफ़ाइलर का इस्तेमाल किया जा सकता है. ज़्यादा जानकारी के लिए, सीपीयू प्रोफ़ाइलर की मदद से सीपीयू की गतिविधि की जांच करना लेख पढ़ें.

अपने ऐप्लिकेशन और गतिविधियों के onCreate तरीकों में इनलाइन ट्रेसिंग की मदद से, संभावित रुकावटों के बारे में भी अहम जानकारी हासिल की जा सकती है. इनलाइन ट्रेसिंग के बारे में जानने के लिए, Trace फ़ंक्शन और सिस्टम ट्रेस करने की प्रोसेस की खास जानकारी वाला दस्तावेज़ देखें.

सामान्य समस्याएं हल करना

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

ऐप्लिकेशन को शुरू होने में ज़्यादा समय लगना

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

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

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

समस्या का पता लगाना

समस्या का पता लगाने के लिए, तरीकों की सूची या इनलाइन ट्रेसिंग का इस्तेमाल किया जा सकता है.

तरीकों की सूची

सीपीयू प्रोफ़ाइलर को चलाने से पता चलता है कि callApplicationOnCreate तरीका, आखिर में आपके com.example.customApplication.onCreate तरीके को कॉल करता है. अगर टूल से पता चलता है कि इन तरीकों को पूरा होने में ज़्यादा समय लग रहा है, तो ज़्यादा जानकारी देखें कि वहां क्या काम हो रहा है.

इनलाइन ट्रेसिंग

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

  • आपके ऐप्लिकेशन का शुरुआती onCreate फ़ंक्शन.
  • कोई भी ग्लोबल सिंगलटन ऑब्जेक्ट जिसे आपका ऐप्लिकेशन शुरू करता है.
  • कोई भी डिस्क I/O, डीसीरियलाइज़ेशन या टाइट लूप, जो बॉटलनेक के दौरान हो सकता है.

समस्या का समाधान

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

इसके अलावा, Hilt जैसे डिपेंडेंसी इंजेक्शन फ़्रेमवर्क का इस्तेमाल करें. यह फ़्रेमवर्क, ऑब्जेक्ट और डिपेंडेंसी को पहली बार इंजेक्ट किए जाने पर उन्हें बनाता है.

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

ज़्यादा गतिविधि शुरू करना

गतिविधि बनाने में अक्सर बहुत ज़्यादा ओवरहेड काम करना पड़ता है. अक्सर, इस काम को ऑप्टिमाइज़ करने के अवसर होते हैं, ताकि परफ़ॉर्मेंस को बेहतर बनाया जा सके. इनमें ये सामान्य समस्याएं शामिल हैं:

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

समस्या का पता लगाना

इस मामले में भी, तरीकों की सूची और इनलाइन ट्रेसिंग, दोनों काम की हो सकती हैं.

तरीकों की सूची

सीपीयू प्रोफ़ाइलर का इस्तेमाल करते समय, अपने ऐप्लिकेशन के Application सबक्लास कंस्ट्रक्टर और com.example.customApplication.onCreate तरीकों पर ध्यान दें.

अगर टूल से पता चलता है कि इन तरीकों को पूरा होने में ज़्यादा समय लग रहा है, तो ज़्यादा जानकारी देखें कि वहां क्या काम हो रहा है.

इनलाइन ट्रेसिंग

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

  • आपके ऐप्लिकेशन का शुरुआती onCreate फ़ंक्शन.
  • कोई भी ग्लोबल सिंगलटन ऑब्जेक्ट जिसे यह शुरू करता है.
  • कोई भी डिस्क I/O, डीसीरियलाइज़ेशन या टाइट लूप, जो बॉटलनेक के दौरान हो सकता है.

समस्या का समाधान

ऐसी कई समस्याएं हो सकती हैं जिनकी वजह से आपके कैंपेन की परफ़ॉर्मेंस पर असर पड़ सकता है. हालांकि, आम तौर पर होने वाली दो समस्याएं और उनके समाधान यहां दिए गए हैं:

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

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

कस्टम स्प्लैश स्क्रीन

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

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

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

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

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