डिवेलपमेंट में लगना — यह क्या है, कारण और ऑप्टिमाइजेशन के तरीके

लेखक: IT Sectr प्रकाशित: 2026-07-28 पढ़ने का समय: 8 मिनट

लगना एक उपयोगकर्ता द्वारा बताई गई स्थिति है जब कोई मोबाइल ऐप धीमे और अनियमित रूप से चलता है: कभी सामान्य रूप से प्रतिक्रिया करता है, तो कभी अचानक कुछ सेकंड के लिए फ्रीज़ हो जाता है। त्वरित संदर्भ में, “लगना” का अर्थ है बार-बार की GC रुकावटों, मुख्य थ्रेड के सिंक्रोनस ऑपरेशनों द्वारा अवरुद्ध होने और अनुकूलतम डेटा संरचनाओं के कारण होने वाले लैग्स और माइक्रो-फ्रीज़ का संयोजन। Android Performance Benchmarking Guide के अनुसार, प्रतिक्रिया समय को 300 मीलीसेकंड से घटाकर 100 मीलीसेकंड करने से उपयोगकर्ता प्रतिधारण में 25% की वृद्धि होती है। लगने का निदान करने के लिए CPU और मेमरी प्रोफाइलिंग के साथ कचरा संग्रहण आवृत्ति विश्लेषण की आवश्यकता होती है।

मुख्य बातें

  • लगना एप्लिकेशन की एक रुक-रुक कर धीमी होने की स्थिति है, जो सामान्य प्रदर्शन के साथ बारी-बारी बदलती रहती है
  • मुख्य कारण — बार-बार की GC रुकावटें, UI थ्रेड पर सिंक्रोनस ऑपरेशन, बिना पेजिनेशन के अडाप्टर्स में डेटा की बड़ी मात्रा
  • निदान के लिए अवरुद्धता खोजने के लिए CPU Profiler और GC आवृत्ति और अवधि का विश्लेषण करने के लिए Memory Profiler की आवश्यकता होती है
  • समाधान में पेजिनेशन (Paging 3) लागू करना, Room के माध्यम से SQL क्वेरीज़ को ऑप्टिमाइज़ करना और भारी कार्यों को WorkManager में डालना शामिल है
  • रोकथाम — Benchmark Baseline Profiles, AOT कंपाइलेशन, हॉट कोड पाथ में आवंटन को न्यूनतम करना

मोबाइल डिवेलपमेंट में “लगने” का क्या मतलब है

लगना एक अनौपचारिक शब्द है जिसका उपयोग उपयोगकर्ता व्यक्तिगत रूप से धीमे एप्लिकेशन प्रदर्शन का वर्णन करने के लिए करते हैं। लैग के विपरीत, जो एक स्थिर विलंब के रूप में प्रगट होता है, लगना अनियमित फ्रीज़ से मिलकर बनता है: ऐप कई सेकंड तक बहुत अच्छी तरह से काम कर सकता है और फिर अचानक 1–3 सेकंड के लिए “सोचने” लग सकता है।

परिघटना का त्वरित विवरण

प्रोफाइलिंग परिप्रेक्ष्य से, लगना छूटे हुए फ्रेम्स (jank) की एक शृंखला के रूप में प्रगट होता है जिसकी चोटी देरी 100 मीलीसेकंड से अधिक होती है। FPS ग्राफ पर, यह तीखी गिरावट के रूप में दिखता है: 60 → 20 → 55 → 10 फ्रेम प्रति सेकंड। समान रूप से कम FPS वाले लैग के विपरीत, लगने में स्पष्ट परिवर्तनशीलता होती है।

उपयोगकर्ता धारणा

जब कोई एप्लिकेशन लगता है, तो उपयोगकर्ता धीमापन के तर्क को नहीं समझ पाता: स्क्रीन आसानी से स्क्रॉल हो सकती है और फिर अचानक एक सेकंड के लिए रुक सकती है। यह निराशा का कारण बनता है और एप्लिकेशन में विश्वास कम करता है। Google के अनुसार, 53% उपयोगकर्ता किसी साइट या एप्लिकेशन को छोड़ देते हैं अगर लोडिंग में 3 सेकंड से अधिक समय लगता है।

ऐप्स में अचानक धीमा होने के कारण

लगने की अनियमित प्रकृति इशारा करती है कि समस्या लगातार ओवरलोड के बजाय इवेंट-ड्राइवन कारकों के कारण होती है। आइए विशिष्ट परिदृश्यों की जांच करें।

ऑब्जेक्ट आवंटन के दौरान GC रुकावटें

Android पर, ART रनटाइम में, कचरा संग्रहण एप्लिकेशन के सभी थ्रेड्स को रोक देता है। अगर कोड बहुत से अस्थायी ऑब्जेक्ट बनाता है — उदाहरण के लिए, हर onBindViewHolder कॉल पर कॉनकटेनेशन के माध्यम से एक नया String बनाना — GC अधिक बार चलता है। हीप आकार और ऑब्जेक्ट पीढ़ी के आधार पर एक रुकावट 5–50 मीलीसेकंड तक रह सकती है। उपयोगकर्ता इसे अचानक “सोचने” के रूप में महसूस करता है।

UI थ्रेड पर सिंक्रोनस SQL क्वेरीज़

Android पर Room और iOS पर Core Data असिंक्रोनस क्वेरीज़ का समर्थन करते हैं, लेकिन डिवेलपर अक्सर सरलता के लिए getValue() कॉल करते हैं या runBlocking के माध्यम से क्वेरीज़ चलाते हैं। 10,000 पंक्तियों की टेबल पर जॉइन के साथ एक भारी SELECT में 200–500 मीलीसेकंड लग सकते हैं, जो उस समय के लिए UI को पूरी तरह से ब्लॉक कर देता है।

बिना डाउनस्केल के इमेज डिकोडिंग

कैमरा इमेज (12 MP, 4000x3000 पिक्सल) को बिना स्केलिंग के लोड करने में Bitmap डिकोडिंग में 200 मीलीसेकंड तक लग सकते हैं। यदि इमेज असिंक्रोनस रूप से लोड की जाती हैं लेकिन बिना किसी बउंडेड थ्रेड पूल के, तो 5–6 डिकोड को एक साथ चलाने से CPU ओवरलोड हो सकता है, जिससे स्थानांतरित मन्दता हो सकती है।

  • Android — लूप में स्ट्रिंग कॉनकटेनेशन, हॉट पाथ में ऑब्जेक्ट निर्माण, बिना inSampleSize के Bitmap
  • iOS — बड़ी संख्या में ऑब्जेक्ट के साथ ऑटोरिलीज़ पूल, बिना स्केलिंग के imageWithContentsOfFile, सिंक्रोनस URLSession
  • क्रॉस-प्लेटफ़ॉर्म — UI थ्रेड पर JSON पार्सिंग, सर्वर प्रतिक्रिया की प्रतीक्षा करते हुए मुख्य थ्रेड पर डेटा लोडिंग

Android और iOS पर फ्रीज़ का निदान कैसे करें

अनियमित मन्दता का निदान लगातार लैग्स का निदान करने से कहीं अधिक कठिन है क्योंकि हर बार चलाने पर समस्या दोबारा उत्पन्न नहीं हो सकती। लंबी अवधि में संख्याएं एकत्रित करने की आवश्यकता होती है।

GC इवेंट रिकॉर्डिंग के साथ Memory Profiler

Android Studio Memory Profiler न केवल मेमरी उपयोग दिखाता है बल्कि GC इवेंट भी दिखाता है: आवृत्ति, प्रकार (Concurrent, Full), अवधि। यदि निष्क्रिय अवस्था में GC हर 5 सेकंड में एक बार से अधिक होता है — तो यह अत्यधिक आवंटन का संकेत है। लगने के क्षण हीप डंप लेने से पता चलता है कि कौन से ऑब्जेक्ट मेमरी पर कब्जा कर रहे हैं।

Allocation Tracking के साथ Xcode Instruments

iOS पर, ऑब्जेक्ट निर्माण और मुक्ति को ट्रेक करने के लिए Instruments में Allocations टेम्पलेट का उपयोग करें। पीढ़ी (Generations) सक्षम करें — ये आपको कार्रवाईओं के बीच हीप स्नैपशॉट लेने और यह देखने की अनुमति देते हैं कि कौन से ऑब्जेक्ट मेमरी में रहते हैं। स्थायी ऑब्जेक्ट जो मुक्त नहीं होते हैं, मेमरी संचय और बद्में रुकावटों का स्रोत हैं।

Android पर JankStats API

JankStats एक Android लाइब्रेरी है जो रियल टाइम में छूटे हुए फ्रेम मीट्रिक्स एकत्रित करती है। यह प्रत्येक jank को वर्तमान परिदृश्य (उदाहरण के लिए, “लिस्ट स्क्रॉलिंग”, “स्क्रीन खोलना”) से जोड़ती है, जिससे यह समझना संभव हो जाता है कि कौन सा विशिष्ट कार्य लगने को ट्रिगर करता है।

Android पर फ्रीज़ ट्रेकिंग के लिए JankStats को एकीकृत करने का उदाहरण:

kotlin
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")
            }
        }
    }
}

धीमे प्रदर्शन को खत्म करने के तरीके

लगने को खत्म करने के लिए प्रत्येक कारण पर लक्षित कार्य की आवश्यकता होती है। कोई सार्वभौमिक समाधान नहीं है — विशिष्ट प्रदर्शन प्रोफ़ाइल के विश्लेषण की आवश्यकता है।

Paging 3 के माध्यम से पेजिनेशन लागू करना

यदि किसी लिस्ट में 1000+ आएटम हैं और सभी एक साथ लोड किए जाते हैं — तो यह निश्चित रूप से लगना है। Android पर Paging 3 और iOS पर NSFetchedResultsController उपयोगकर्ता के स्क्रॉल करने पर डेटा को भागों में लोड करते हैं। उपयोगकर्ता को केवल पहले 10–20 आएटम दिखाई देते हैं; बाकी पृष्ठभूमि में लोड होते हैं।

SQL क्वेरीज़ और इंडेक्स को ऑप्टिमाइज़ करना

Room Android Studio में निरीक्षण उपकरण के माध्यम से क्वेरीज़ का प्रोफ़ाइलिंग करने की अनुमति देता है: निष्पादन समय, लौटाई गई पंक्तियों की संख्या और क्वेरी योजना दिखाई देती है। WHERE और ORDER BY कॉलम पर इंडेक्स जोड़ने से क्वेरी समय को 300 मीलीसेकंड से घटाकर 5 मीलीसेकंड किया जा सकता है। iOS पर, Instruments में Core Data Profiler द्वारा एक समान जांच की जाती है।

कार्यों को WorkManager में स्थानांतरित करना

पृष्ठभूमि सिंक करना, फ़ाइल डाउनलोड, डेटा प्रोसेसिंग — यह सब WorkManager (Android) या Background Tasks (iOS) के माध्यम से निष्पादित होना चाहिए। यदि सिंक UI थ्रेड पर चलती है, तो ऐप निष्पादन के दौरान लगेगा। WorkManager बैटरी और नेटवर्क स्थिति के बारे में जागरूकता के साथ एक पृष्ठभूमि थ्रेड पर निष्पादन की गारंटी देता है।

Android पर WorkManager के माध्यम से पृष्ठभूमि सिंक का उदाहरण:

kotlin
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()
        }
    }
}

डिवेलपमेंट स्टेज पर लगने से रोकथाम

कुशल मेमरी और थ्रेड प्रबंधन के सिद्धांतों का पालन करके कोडिंग स्टेज पर ही लगने से बचा जा सकता है।

AOT कंपाइलेशन के लिए Baseline Profiles

Baseline Profiles कक्षाओं और विधियों की एक सूची है जिन्हें Android JIT के बजाय पहले से (AOT) संकलित करता है। बिना प्रोफ़ाइल के, प्रत्येक नई स्क्रीन पहली बार खुलने पर संकलित होती है, जिससे 100–500 मीलीसेकंड की देरी होती है। मुख्य स्क्रीन्स के लिए एक Baseline Profile तैयार करें और baseline-profile-gradle-plugin के माध्यम से Gradle में जनरेशन सक्षम करें।

हॉट पाथ में आवंटन को न्यूनतम करना

हॉट पाथ वह कोड है जो हर फ्रेम पर निष्पादित होता है: onBindViewHolder, draw, layoutSubviews। इन विधियों में ऑब्जेक्ट बनाने से बचें: ऑब्जेक्ट पूल, कॉनकटेनेशन के बजाय StringBuilder, फ़ॉर्मेटेड स्ट्रिंग्स और फ़ॉर्मैटर कैश करें। हर अतिरिक्त आवंटन अगले GC को करीब लाता है।

CI में Baseline Profiles के माध्यम से प्रोफ़ाइलिंग

अपने CI पाइपलाइन में लिस्ट स्क्रॉलिंग और स्क्रीन खोलने के परिदृश्य के साथ Macrobenchmark जोड़ें। एक सीमा निर्धारित करें: 99वाँ पर्सेन्टाइल फ्रेम समय 16 मीलीसेकंड से अधिक नहीं होना चाहिए। यदि सीमा पार हो जाती है — तो बिल्ड को ऑप्टिमाइजेशन तक अस्वीकार कर दिया जाता है।

  • Android — Baseline Profiles, Macrobenchmark, JankStats, penaltyDeath के साथ StrictMode
  • iOS — MetricKit, os_signpost, XCTMetric, Debug स्कीम में Main Thread Checker
  • सामान्य दृष्टिकोण — नियमित प्रोफ़ाइलिंग, हॉट पाथ में आवंटन पर केंद्रित कोड समीक्षाएँ

अक्सर पूछे जाने वाले प्रश्न

लगना सामान्य लैग से कैसे अलग है?

लैग एक स्थिर विलंब है (उदाहरण के लिए, हर टैप पर 200 मीलीसेकंड). लगना अनियमित है: ऐप सामान्य रूप से काम करता है, फिर अचानक 1–3 सेकंड के लिए धीमा हो जाता है, फिर सामान्य हो जाता है। कारण GC रुकावटों या डेटाबेस क्वेरीज़ जैसे इवेंट-ड्राइवन कारक हैं।

Android पर GC रुकावट आवृत्ति कैसे मापें?

Android Studio में Memory Profiler का उपयोग करें: Memory टैब GC इवेंट को अवधि के सاथ दिखाता है। प्रोडक्शन मॉनिटरिंग के लिए, कस्टम ट्रेस के साथ Firebase Performance Monitoring को एकीकृत करें। iOS पर, Malloc Debug सक्षम करें और Instruments में आवंटन पीढ़ियों को चिह्नित करें।

क्या नेटवर्क अनुरोध लगने के कारण हो सकते हैं?

अप्रत्यक्ष रूप से — हाँ। यदि सर्वर प्रतिक्रिया में देरी होती है और UI सिंक्रोनस रूप से इसका इंतजार करता है, तो ऐप फ्रीज़ हो जाता है। यदि अनुरोध असिंक्रोनस है लेकिन प्रतिक्रिया प्रसंस्करण UI थ्रेड पर किया जाता है — तो यह भी लगने का कारण बनेगा। समाधान है कॉरूटिन और प्रगति संकेतकों के साथ असिंक्रोनस प्रसंस्करण।

Kotlin Multiplatform प्रदर्शन को कैसे प्रभावित करता है?

गलत ढंग से उपयोग करने पर, KMP अंतरोपरणीयता के लिए अतिरिक्त रैपर ऑब्जेक्ट उत्पन्न कर सकता है। iOS पर, यह आवंटन आवृत्ति और परिणामस्वरूप ARC रुकावटों को बढ़ाता है। @ObjCName का उपयोग करें, expect/actual को ऑप्टिमाइज़ करें और UI हॉट पाथ से शेयर कोड के बार-बार कॉल से बचें।

क्या Android पर हीप आकार बढ़ाने से मदद मिलती है?

android:largeHeap=”true” के माध्यम से हीप बढ़ाने से GC में देरी होती है लेकिन आवंटन का कारण समाप्त नहीं होता। जब GC आखिरकार चलता है, तो रुकावट अधिक लंबी होगी क्योंकि अधिक ऑब्जेक्टों को पार करने की आवश्यकता होती है। समाधान है हीप का विस्तार नहीं, बल्कि आवंटन की संख्या कम करना।

सारांश

  • लगना एक अनियमित एप्लिकेशन मन्दता है जो इवेंट-ड्राइवन कारकों (GC रुकावटें, सिंक्रोनस क्वेरीज़, इमेज डिकोडिंग) के कारण होती है
  • निदान के लिए Memory Profiler, Android पर JankStats और iOS पर Instruments में Allocation Tracking की आवश्यकता होती है
  • मुख्य कारण — बार-बार की GC रुकावटें, पेजिनेशन की कमी, अनुकूलतम SQL क्वेरीज़ और UI थ्रेड पर सिंक्रोनस प्रसंस्करण
  • समाधान — Paging 3, WorkManager, DB इंडेक्स ऑप्टिमाइजेशन, इमेज डाउनस्केलिंग और आवंटन न्यूनतमकरण
  • रोकथाम — Baseline Profiles, Macrobenchmark, StrictMode, हॉट पाथ जांच के साथ कोड समीक्षाएँ
  • उपकरण — प्रोडक्शन लग मॉनिटरिंग के लिए JankStats, Firebase Performance, MetricKit
  • अनुशंसा: 99वें फ्रेम पर्सेन्टाइल पर 16 मीलीसेकंड की सीमा के साथ CI में नियमित Macrobenchmark रन लागू करें

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें