لیگ موبائل ایپ میں صارف کے عمل اور انٹرفیس کے ردعمل کے درمیان ایک نمایاں تاخیر ہے، جو مرکزی تھریڈ کے اوورلوڈ، میموری لیک یا غیر موزوں I/O آپریشنز کی وجہ سے ہوتی ہے۔ منطقی غلطیوں سے منسلک گلیچ کے برعکس، لیگ کارکردگی کا مسئلہ ہے: ایپ درست کام کرتی ہے لیکن سست۔ AppDynamics Mobile App Performance Report 2024 کے مطابق، 62% صارفین ایپ ڈیلیٹ کر دیتے ہیں اگر یہ 3 سیکنڈ سے زیادہ سست ہو۔ لیگ کی تشخیص کے لیے Android Studio Profiler اور Xcode Instruments کے ساتھ CPU، میموری اور نیٹ ورک پروفائلنگ ضروری ہے۔
اہم نکات
لیگ موبائل ایپ میں صارف کے عمل (چھونا، سوائپ کرنا، ٹیکسٹ داخل کرنا) اور انٹرفیس کے جواب کے درمیان ایک موضوعی طور پر قابلِ احساس تاخیر ہے۔ تکنیکی طور پر، لیگ ان پٹ ایونٹ اور مکمل فریم رینڈر کے درمیان وقت کے طور پر ماپا جاتا ہے: آرام دہ حد 100 ms تک، قابلِ توجہ 200 ms سے، تنقیدی 500 ms سے زیادہ۔
صارف کی اصطلاحات میں، “لیگ” اور “سست” اکثر مترادف کے طور پر استعمال ہوتے ہیں، لیکن تکنیکی طور پر لیگ ایک مقررہ تاخیر ہے (مثلاً، ہر ٹیپ پر 300 ms)، جبکہ “سست” ایک وقفے وقفے سے سستی ہے: ایپ ہموار کام کرتی ہے پھر ایک سیکنڈ کے لیے منجمد ہو جاتی ہے۔ گلیچ، لیگ کے برعکس، رفتار سے نہیں بلکہ ڈسپلے کی درستگی سے متعلق ہے۔
Google Play اور App Store ایپس کی درجہ بندی کرتے وقت کارکردگی کے میٹرکس پر غور کرتے ہیں۔ ANR کی شرح، jank کی تعدد اور شروع ہونے کا وقت تلاش کی مرئیت اور انسٹال تبادلوں کو متاثر کرتا ہے۔ مسلسل لیگ والی ایپ پہلے لانچ کے بعد 40% تک صارفین کھو دیتی ہے۔
لیگ اس وقت ہوتی ہے جب مرکزی UI تھریڈ 60 FPS (16.6 ms فی فریم) یا 120 FPS (8.3 ms) پر فریم پروسیس کرنے میں ناکام ہو۔ آئیے تاخیر کے اہم ذرائع دیکھتے ہیں۔
UI تھریڈ میں کوئی بھی ہم وقت ساز آپریشن — SharedPreferences سے پڑھنا، suspend کے بغیر Room کے ذریعے ڈیٹا بیس کے ساتھ کام کرنا، تصویر کو Bitmap میں ڈی کوڈ کرنا — فریم رینڈرنگ کو روکتا ہے۔ Android پر یہ jank کا سبب بنتا ہے، iOS پر یہ Core Animation رینڈر میں تاخیر کا سبب بنتا ہے۔
جب Android پر کچرا اٹھانے والا یا iOS پر ARC میموری خالی کرتا ہے، تو تمام تھریڈ رک جاتے ہیں۔ بار بار GC کی روک اس وقت ہوتی ہے جب بہت سے عارضی آبجیکٹ بنائے جاتے ہیں — مثال کے طور پر، ہر اڈیپٹر کال پر نیا ViewHolder انسٹنس بنانا۔ یہ جھٹکے دار اسکرولنگ کے طور پر ظاہر ہوتا ہے۔
نیسٹڈ ConstraintLayout، متعدد LinearLayout، اوورلیپنگ View — ہر نیسٹنگ لیول measure اور layout pass کا وقت بڑھاتا ہے۔ Xcode اشارہ کرتا ہے کہ گہری پرت کا درجہ بندی (10 سطحوں سے زیادہ) FPS میں 20-30% کی کمی کا سبب بنتی ہے۔
لیگ کی وجوہات کی نشاندہی کرنے کے لیے IDE میں بنے پروفائلرز اور سسٹم مانیٹرنگ ٹولز استعمال کیے جاتے ہیں۔ ہر ٹول اپنا کام حل کرتا ہے۔
CPU Profiler دکھاتا ہے کہ کون سے طریقے CPU وقت لیتے ہیں اور کون سے تھریڈ میں وہ عمل میں آتے ہیں۔ اگر بھاری حساب کا طریقہ مرکزی تھریڈ میں چلتا ہے — یہ بنیادی وجہ ہے۔ sample Java Method کو فعال کرکے ٹریس ریکارڈ کرنے سے کسی بھی لمحے کال اسٹیک دیکھنے اور ہاٹ سپاٹ تلاش کرنے کی اجازت ملتی ہے۔
iOS کے لیے مساوی ٹول — Time Profiler — ہر ملی سیکنڈ میں اسٹیک نمونے جمع کرتا ہے اور دکھاتا ہے کہ ہر طریقہ CPU وقت کا کتنا فیصد لیتا ہے۔ Main Thread Only جھنڈے کے ساتھ مجموعہ صرف مرکزی تھریڈ آپریشنز کو فلٹر کرتا ہے، براہ راست لیگ کے ذرائع کی طرف اشارہ کرتا ہے۔
سست نیٹ ورک درخواستیں لیگ کا تاثر دیتی ہیں چاہے UI تھریڈ بلاک نہ ہو۔ Android Studio میں Network Profiler اور Xcode میں Network Link Conditioner سست کنکشن کی نقل کرنے اور حقیقی حالات میں ایپ کے رویے کی نشاندہی کرنے کی اجازت دیتے ہیں۔ پیش رفت کے بغیر ٹکڑوں میں جوابات اور بڑے JSON پے لوڈز ظاہری لیگ کے عام ذرائع ہیں۔
OkHttp کے ساتھ وقت کی پیمائش سمیت نیٹ ورک کی درخواست کی پروفائلنگ کی مثال:
class TimingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val start = System.nanoTime()
val response = chain.proceed(chain.request())
val duration = (System.nanoTime() - start) / 1_000_000
Log.d("Timing", "Request took $duration ms")
return response
}
}
لیگ کو حل کرنے کے لیے منظم کام کی ضرورت ہے: ایک طریقہ کو بہتر بنانے سے لے کر آرکیٹیکچرل تبدیلیوں تک۔ آئیے سب سے مؤثر تکنیکوں کو دیکھتے ہیں۔
نیٹ ورک کی درخواستوں کے لیے Dispatchers.IO اور حسابات کے لیے Dispatchers.Default کے ساتھ Kotlin Coroutines اس بات کو یقینی بناتے ہیں کہ مرکزی تھریڈ UI کے لیے خالی رہے۔ iOS پر Grand Central Dispatch پس منظر کے کاموں کے لیے queue .global(qos: .userInitiated) اور UI اپ ڈیٹس کے لیے .main کے ساتھ معیاری نقطہ نظر ہے۔ قطاروں کے درمیان sync آپریشنز سے گریز کریں۔
Android پر RecyclerView اور iOS پر UICollectionView کو درست ترتیب کی ضرورت ہے: onBindViewHolder میں کم سے کم آبجیکٹ تخلیق کے ساتھ ViewHolder، تبدیلیوں کی گنتی کے لیے DiffUtil، ڈیٹا کی پیشگی لوڈنگ کے لیے prefetching۔ iOS پر دستی انتظام کے بغیر متحرک اپ ڈیٹس کے لیے diffable data source استعمال کریں۔
ہر اسکرول پر ایک ہی تصویر لوڈ کرنا یقینی لیگ ہے۔ Coil (Android) اور Kingfisher (iOS) تصاویر کو میموری اور ڈسک پر کیش کرتے ہیں، بار بار درخواستوں پر فوری ڈسپلے کو یقینی بناتے ہیں۔ ڈیٹا کے لیے، Flow یا Combine پر مبنی کیشنگ پرت کے ساتھ Room استعمال کریں۔
Android پر Coil کے ساتھ تصویر کیشنگ ترتیب دینے کی مثال:
val imageLoader = ImageLoader(context) {
memoryCachePolicy(CachePolicy.ENABLED)
diskCachePolicy(CachePolicy.ENABLED)
crossfade(true)
size(512, 512)
}
// Loading with auto-caching enabled
imageView.load("https://example.com/image.jpg") {
placeholder(R.drawable.placeholder)
error(R.drawable.error)
}
لیگ کو روکنا پروڈکشن میں اسے ٹھیک کرنے سے سستا ہے۔ احتیاطی تدابیر ٹول اور آرکیٹیکچر کی سطح پر ڈویلپمنٹ کے عمل میں شامل کی جاتی ہیں۔
StrictMode ایک بلٹ ان Android ٹول ہے جو ڈویلپمنٹ کے دوران مرکزی تھریڈ پر حادثاتی I/O آپریشنز اور نیٹ ورک کالز کا پتہ لگاتا ہے۔ اسے سنگین خلاف ورزیوں کے لیے penaltyDeath پالیسی کے ساتھ Application.onCreate میں فعال کریں۔ یہ یقینی بنانے کا واحد طریقہ ہے کہ ڈویلپر کمٹ سے پہلے مسئلہ دیکھے۔
iOS کے لیے مساوی — Xcode میں Main Thread Checker، Runtime Sanitization کا حصہ — خود بخود چیک کرتا ہے کہ تمام UIKit اور AppKit کالز مرکزی تھریڈ پر عمل میں آئیں۔ اسے Debug بلڈ اسکیم میں فعال کریں اور CI میں صفر وارننگ کا ہدف بنائیں۔
شروع ہونے کے وقت، اسکرول FPS اور میموری کے استعمال کی پیمائش کرنے کے لیے اپنی CI پائپ لائن میں Macrobenchmark (Android) اور XCTMetrics (iOS) رنز شامل کریں۔ حدیں مقرر کریں: اگر نیا کمٹ شروع ہونے کا وقت 5% سے زیادہ بڑھاتا ہے — بلڈ ناکام ہو جاتا ہے۔
اکثر پوچھے گئے سوالات
لیگ تاخیر کا ایک موضوعی احساس ہے جو زیادہ FPS پر بھی ہو سکتا ہے اگر تاخیر رینڈرنگ کے بجائے ان پٹ پروسیسنگ وقت کی وجہ سے ہو۔ کم FPS (30 fps سے کم) لیگ کی ایک وجہ ہے، لیکن واحد نہیں۔
فریموں کے درمیان وقت کی پیمائش کرنے کے لیے Android پر Frame Timing API (Choreographer) اور iOS پر CADisplayLink استعمال کریں۔ Google Play Vitals حقیقی حالات میں jank کی شرح دکھاتا ہے۔ درست پیمائش کے لیے اسکرول منظرناموں کے ساتھ Macrobenchmark استعمال کریں۔
پرانے آلات میں CPU کور کم، RAM کم اور میموری سست ہوتی ہے۔ ایک آپریشن جو فلیگ شپ پر 5 ms لیتا ہے، بجٹ ڈیوائس پر 50 ms لے سکتا ہے۔ نچلے حصے کے آلات پر کارکردگی کی جانچ کریں اور AOT کمپائلیشن کے لیے Baseline Profiles مرتب کریں۔
جی ہاں، یہ سب سے مؤثر طریقوں میں سے ایک ہے۔ ہائی ریزولوشن والی تصاویر ڈی کوڈنگ کے لیے بہت زیادہ میموری اور CPU وقت لیتی ہیں۔ View سائز تک downscale، WebP (Android) اور HEIC (iOS) فارمیٹس، اور Coil یا Kingfisher کے ذریعے کیشنگ استعمال کریں۔
SwiftUI diffing کے ذریعے اپ ڈیٹس کو خود بخود بہتر بناتا ہے، ڈیٹا تبدیل ہونے پر لیگ کے خطرے کو کم کرتا ہے۔ تاہم، پیچیدہ درجہ بندی اور بار بار body کی تعمیر نو FPS میں کمی کا سبب بن سکتی ہے۔ UIKit کارکردگی پر زیادہ کنٹرول دیتا ہے لیکن دستی اصلاح کی ضرورت ہوتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں