लगना एक उपयोगकर्ता द्वारा बताई गई स्थिति है जब कोई मोबाइल ऐप धीमे और अनियमित रूप से चलता है: कभी सामान्य रूप से प्रतिक्रिया करता है, तो कभी अचानक कुछ सेकंड के लिए फ्रीज़ हो जाता है। त्वरित संदर्भ में, “लगना” का अर्थ है बार-बार की GC रुकावटों, मुख्य थ्रेड के सिंक्रोनस ऑपरेशनों द्वारा अवरुद्ध होने और अनुकूलतम डेटा संरचनाओं के कारण होने वाले लैग्स और माइक्रो-फ्रीज़ का संयोजन। Android Performance Benchmarking Guide के अनुसार, प्रतिक्रिया समय को 300 मीलीसेकंड से घटाकर 100 मीलीसेकंड करने से उपयोगकर्ता प्रतिधारण में 25% की वृद्धि होती है। लगने का निदान करने के लिए CPU और मेमरी प्रोफाइलिंग के साथ कचरा संग्रहण आवृत्ति विश्लेषण की आवश्यकता होती है।
मुख्य बातें
लगना एक अनौपचारिक शब्द है जिसका उपयोग उपयोगकर्ता व्यक्तिगत रूप से धीमे एप्लिकेशन प्रदर्शन का वर्णन करने के लिए करते हैं। लैग के विपरीत, जो एक स्थिर विलंब के रूप में प्रगट होता है, लगना अनियमित फ्रीज़ से मिलकर बनता है: ऐप कई सेकंड तक बहुत अच्छी तरह से काम कर सकता है और फिर अचानक 1–3 सेकंड के लिए “सोचने” लग सकता है।
प्रोफाइलिंग परिप्रेक्ष्य से, लगना छूटे हुए फ्रेम्स (jank) की एक शृंखला के रूप में प्रगट होता है जिसकी चोटी देरी 100 मीलीसेकंड से अधिक होती है। FPS ग्राफ पर, यह तीखी गिरावट के रूप में दिखता है: 60 → 20 → 55 → 10 फ्रेम प्रति सेकंड। समान रूप से कम FPS वाले लैग के विपरीत, लगने में स्पष्ट परिवर्तनशीलता होती है।
जब कोई एप्लिकेशन लगता है, तो उपयोगकर्ता धीमापन के तर्क को नहीं समझ पाता: स्क्रीन आसानी से स्क्रॉल हो सकती है और फिर अचानक एक सेकंड के लिए रुक सकती है। यह निराशा का कारण बनता है और एप्लिकेशन में विश्वास कम करता है। Google के अनुसार, 53% उपयोगकर्ता किसी साइट या एप्लिकेशन को छोड़ देते हैं अगर लोडिंग में 3 सेकंड से अधिक समय लगता है।
लगने की अनियमित प्रकृति इशारा करती है कि समस्या लगातार ओवरलोड के बजाय इवेंट-ड्राइवन कारकों के कारण होती है। आइए विशिष्ट परिदृश्यों की जांच करें।
Android पर, ART रनटाइम में, कचरा संग्रहण एप्लिकेशन के सभी थ्रेड्स को रोक देता है। अगर कोड बहुत से अस्थायी ऑब्जेक्ट बनाता है — उदाहरण के लिए, हर onBindViewHolder कॉल पर कॉनकटेनेशन के माध्यम से एक नया String बनाना — GC अधिक बार चलता है। हीप आकार और ऑब्जेक्ट पीढ़ी के आधार पर एक रुकावट 5–50 मीलीसेकंड तक रह सकती है। उपयोगकर्ता इसे अचानक “सोचने” के रूप में महसूस करता है।
Android पर Room और iOS पर Core Data असिंक्रोनस क्वेरीज़ का समर्थन करते हैं, लेकिन डिवेलपर अक्सर सरलता के लिए getValue() कॉल करते हैं या runBlocking के माध्यम से क्वेरीज़ चलाते हैं। 10,000 पंक्तियों की टेबल पर जॉइन के साथ एक भारी SELECT में 200–500 मीलीसेकंड लग सकते हैं, जो उस समय के लिए UI को पूरी तरह से ब्लॉक कर देता है।
कैमरा इमेज (12 MP, 4000x3000 पिक्सल) को बिना स्केलिंग के लोड करने में Bitmap डिकोडिंग में 200 मीलीसेकंड तक लग सकते हैं। यदि इमेज असिंक्रोनस रूप से लोड की जाती हैं लेकिन बिना किसी बउंडेड थ्रेड पूल के, तो 5–6 डिकोड को एक साथ चलाने से CPU ओवरलोड हो सकता है, जिससे स्थानांतरित मन्दता हो सकती है।
अनियमित मन्दता का निदान लगातार लैग्स का निदान करने से कहीं अधिक कठिन है क्योंकि हर बार चलाने पर समस्या दोबारा उत्पन्न नहीं हो सकती। लंबी अवधि में संख्याएं एकत्रित करने की आवश्यकता होती है।
Android Studio Memory Profiler न केवल मेमरी उपयोग दिखाता है बल्कि GC इवेंट भी दिखाता है: आवृत्ति, प्रकार (Concurrent, Full), अवधि। यदि निष्क्रिय अवस्था में GC हर 5 सेकंड में एक बार से अधिक होता है — तो यह अत्यधिक आवंटन का संकेत है। लगने के क्षण हीप डंप लेने से पता चलता है कि कौन से ऑब्जेक्ट मेमरी पर कब्जा कर रहे हैं।
iOS पर, ऑब्जेक्ट निर्माण और मुक्ति को ट्रेक करने के लिए Instruments में Allocations टेम्पलेट का उपयोग करें। पीढ़ी (Generations) सक्षम करें — ये आपको कार्रवाईओं के बीच हीप स्नैपशॉट लेने और यह देखने की अनुमति देते हैं कि कौन से ऑब्जेक्ट मेमरी में रहते हैं। स्थायी ऑब्जेक्ट जो मुक्त नहीं होते हैं, मेमरी संचय और बद्में रुकावटों का स्रोत हैं।
JankStats एक Android लाइब्रेरी है जो रियल टाइम में छूटे हुए फ्रेम मीट्रिक्स एकत्रित करती है। यह प्रत्येक jank को वर्तमान परिदृश्य (उदाहरण के लिए, “लिस्ट स्क्रॉलिंग”, “स्क्रीन खोलना”) से जोड़ती है, जिससे यह समझना संभव हो जाता है कि कौन सा विशिष्ट कार्य लगने को ट्रिगर करता है।
Android पर फ्रीज़ ट्रेकिंग के लिए JankStats को एकीकृत करने का उदाहरण:
class MainActivity : AppCompatActivity() {
private lateinit var jankStats: JankStats
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
jankStats = JankStats.create(this.window.decorView) { frameData ->
if (frameData.isJank()) {
Log.w("Jank", "Duration=${frameData.durationMs}ms")
}
}
}
}
लगने को खत्म करने के लिए प्रत्येक कारण पर लक्षित कार्य की आवश्यकता होती है। कोई सार्वभौमिक समाधान नहीं है — विशिष्ट प्रदर्शन प्रोफ़ाइल के विश्लेषण की आवश्यकता है।
यदि किसी लिस्ट में 1000+ आएटम हैं और सभी एक साथ लोड किए जाते हैं — तो यह निश्चित रूप से लगना है। Android पर Paging 3 और iOS पर NSFetchedResultsController उपयोगकर्ता के स्क्रॉल करने पर डेटा को भागों में लोड करते हैं। उपयोगकर्ता को केवल पहले 10–20 आएटम दिखाई देते हैं; बाकी पृष्ठभूमि में लोड होते हैं।
Room Android Studio में निरीक्षण उपकरण के माध्यम से क्वेरीज़ का प्रोफ़ाइलिंग करने की अनुमति देता है: निष्पादन समय, लौटाई गई पंक्तियों की संख्या और क्वेरी योजना दिखाई देती है। WHERE और ORDER BY कॉलम पर इंडेक्स जोड़ने से क्वेरी समय को 300 मीलीसेकंड से घटाकर 5 मीलीसेकंड किया जा सकता है। iOS पर, Instruments में Core Data Profiler द्वारा एक समान जांच की जाती है।
पृष्ठभूमि सिंक करना, फ़ाइल डाउनलोड, डेटा प्रोसेसिंग — यह सब WorkManager (Android) या Background Tasks (iOS) के माध्यम से निष्पादित होना चाहिए। यदि सिंक UI थ्रेड पर चलती है, तो ऐप निष्पादन के दौरान लगेगा। WorkManager बैटरी और नेटवर्क स्थिति के बारे में जागरूकता के साथ एक पृष्ठभूमि थ्रेड पर निष्पादन की गारंटी देता है।
Android पर WorkManager के माध्यम से पृष्ठभूमि सिंक का उदाहरण:
class SyncWorker(context: Context, params: WorkerParameters)
: CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
Log.d("सिंक", "पृष्ठभूमि थ्रेड में डेटा सिंक किया जा रहा है")
syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
कुशल मेमरी और थ्रेड प्रबंधन के सिद्धांतों का पालन करके कोडिंग स्टेज पर ही लगने से बचा जा सकता है।
Baseline Profiles कक्षाओं और विधियों की एक सूची है जिन्हें Android JIT के बजाय पहले से (AOT) संकलित करता है। बिना प्रोफ़ाइल के, प्रत्येक नई स्क्रीन पहली बार खुलने पर संकलित होती है, जिससे 100–500 मीलीसेकंड की देरी होती है। मुख्य स्क्रीन्स के लिए एक Baseline Profile तैयार करें और baseline-profile-gradle-plugin के माध्यम से Gradle में जनरेशन सक्षम करें।
हॉट पाथ वह कोड है जो हर फ्रेम पर निष्पादित होता है: onBindViewHolder, draw, layoutSubviews। इन विधियों में ऑब्जेक्ट बनाने से बचें: ऑब्जेक्ट पूल, कॉनकटेनेशन के बजाय StringBuilder, फ़ॉर्मेटेड स्ट्रिंग्स और फ़ॉर्मैटर कैश करें। हर अतिरिक्त आवंटन अगले GC को करीब लाता है।
अपने CI पाइपलाइन में लिस्ट स्क्रॉलिंग और स्क्रीन खोलने के परिदृश्य के साथ Macrobenchmark जोड़ें। एक सीमा निर्धारित करें: 99वाँ पर्सेन्टाइल फ्रेम समय 16 मीलीसेकंड से अधिक नहीं होना चाहिए। यदि सीमा पार हो जाती है — तो बिल्ड को ऑप्टिमाइजेशन तक अस्वीकार कर दिया जाता है।
अक्सर पूछे जाने वाले प्रश्न
लैग एक स्थिर विलंब है (उदाहरण के लिए, हर टैप पर 200 मीलीसेकंड). लगना अनियमित है: ऐप सामान्य रूप से काम करता है, फिर अचानक 1–3 सेकंड के लिए धीमा हो जाता है, फिर सामान्य हो जाता है। कारण GC रुकावटों या डेटाबेस क्वेरीज़ जैसे इवेंट-ड्राइवन कारक हैं।
Android Studio में Memory Profiler का उपयोग करें: Memory टैब GC इवेंट को अवधि के सاथ दिखाता है। प्रोडक्शन मॉनिटरिंग के लिए, कस्टम ट्रेस के साथ Firebase Performance Monitoring को एकीकृत करें। iOS पर, Malloc Debug सक्षम करें और Instruments में आवंटन पीढ़ियों को चिह्नित करें।
अप्रत्यक्ष रूप से — हाँ। यदि सर्वर प्रतिक्रिया में देरी होती है और UI सिंक्रोनस रूप से इसका इंतजार करता है, तो ऐप फ्रीज़ हो जाता है। यदि अनुरोध असिंक्रोनस है लेकिन प्रतिक्रिया प्रसंस्करण UI थ्रेड पर किया जाता है — तो यह भी लगने का कारण बनेगा। समाधान है कॉरूटिन और प्रगति संकेतकों के साथ असिंक्रोनस प्रसंस्करण।
गलत ढंग से उपयोग करने पर, KMP अंतरोपरणीयता के लिए अतिरिक्त रैपर ऑब्जेक्ट उत्पन्न कर सकता है। iOS पर, यह आवंटन आवृत्ति और परिणामस्वरूप ARC रुकावटों को बढ़ाता है। @ObjCName का उपयोग करें, expect/actual को ऑप्टिमाइज़ करें और UI हॉट पाथ से शेयर कोड के बार-बार कॉल से बचें।
android:largeHeap=”true” के माध्यम से हीप बढ़ाने से GC में देरी होती है लेकिन आवंटन का कारण समाप्त नहीं होता। जब GC आखिरकार चलता है, तो रुकावट अधिक लंबी होगी क्योंकि अधिक ऑब्जेक्टों को पार करने की आवश्यकता होती है। समाधान है हीप का विस्तार नहीं, बल्कि आवंटन की संख्या कम करना।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें