Jank ایک اصطلاح ہے جو انفرادی فریموں کے چھوٹ جانے کی وجہ سے انٹرفیس اینیمیشن میں نمایاں رکاوٹ یا “ہچکی” کو ظاہر کرتی ہے۔ موبائل ایپس میں، Jank اس وقت ہوتا ہے جب فریم رینڈرنگ کا وقت ڈسپلے ریفریش ریٹ کے ذریعے مختص کردہ بجٹ سے تجاوز کر جاتا ہے۔ Android Developers، 2025 کے مطابق، Jank “سستی” کے موضوعی احساس کی بنیادی وجہ ہے — ایپ فعال طور پر کامل ہو سکتی ہے، لیکن صارف غیر مستحکم FPS کی وجہ سے اسے سست سمجھتا ہے۔
اہم نکات
Jank کمپیوٹر گرافکس کی ایک اصطلاح ہے جو ایک بصری نقص کو ظاہر کرتی ہے جس میں اینیمیشن ہموار سلائیڈنگ کے بجائے جھٹکوں سے چلتی ہے۔ موبائل ڈویلپمنٹ میں، Jank کو فی یونٹ وقت میں چھوٹے ہوئے فریموں (skipped frames) کی تعداد سے ماپا جاتا ہے۔ اگر سسٹم VSync کے وقت تک فریم تیار کرنے میں ناکام رہتا ہے، تو ڈسپلے پچھلے فریم کو دہراتا ہے — 60 Hz پر 16.6 ms کا وقفہ ہوتا ہے۔ ایک چھوٹا ہوا فریم نظر انداز ہو سکتا ہے، لیکن مسلسل 3–5 چھوٹے ہوئے فریم 50–80 ms کی “رکاوٹ” کا احساس پیدا کرتے ہیں، جسے صارف واضح طور پر محسوس کرتا ہے۔
Jank خاص طور پر ان اینیمیشنز کے لیے اہم ہے جنہیں مستقل رفتار سے چلنا چاہیے: فیڈ سکرولنگ، مینو کھولنے کی اینیمیشن، parallax اثرات، اسکرینوں کے درمیان منتقلی۔ Google UX تحقیق (2024) کے مطابق، جس ایپ میں 3% سے زیادہ سکرول سیشنز میں Jank کی شرح ہے، اسے 0.5% سے کم شرح والی ایپ کے مقابلے میں 22% زیادہ ایک ستارہ والے جائزے ملتے ہیں۔ Android Vitals ٹول خود بخود Jank کو ٹریک کرتا ہے اور اسے شدیدیت کے مطابق درجہ بندی کرتا ہے: اعتدال پسند، شدید اور نازک۔
Jank کی وجوہات کئی زمروں میں تقسیم ہوتی ہیں۔ پہلی — Layout Jank: View کے سائز میں تبدیلی، LayoutTransition اینیمیشنز یا متحرک مواد لوڈنگ کی وجہ سے بار بار requestLayout() کالوں سے پیدا ہوتی ہے۔ ہر requestLayout کال پورے View ذیلی درخت کے لیے Measure + Layout شروع کرتی ہے، جس میں 5–30 ms لگ سکتے ہیں۔ دوسری — Draw Jank: overdraw اور بھاری drawable کے استعمال سے متعلق۔ تیسری — Thread Jank: ہم آہنگ کارروائیوں کی وجہ سے مرکزی تھریڈ کی بلاکنگ — فائل لوڈنگ، مرکزی تھریڈ پر ڈیٹابیس آپریشنز، Bitmap ڈی کوڈنگ۔
چوتھا زمرہ — GC Jank: ART/Dalvik یا Swift ARC میں کوڑا کرکٹ جمع کرنا (Garbage Collection)۔ جب ہیپ میں بہت سے آبجیکٹ جمع ہو جاتے ہیں، GC 5–15 ms کا Stop-The-World وقفہ شروع کرتا ہے۔ Android پر، GC وقفے اکثر لوپس میں بار بار مختص کرنے کے دوران ہوتے ہیں: onDraw() میں آبجیکٹ بنانا، اڈیپٹرز میں مختص کرنا، غیر استعمال شدہ lambda اظہار۔ پانچویں — IPC Jank: مرکزی تھریڈ پر انٹر پروسیس کمیونیکیشن (ContentProvider، Binder)۔ چھٹی — Rendering Jank: غیر موثر شیڈرز یا بڑی ساخت کی وجہ سے سست GPU رینڈرنگ۔
| Jank کی قسم | وجہ | عام دورانیہ | پتہ لگانے کا ٹول |
|---|---|---|---|
| Layout | requestLayout، relayout | 5–30 ms | Perfetto، Systrace |
| Draw | Overdraw، بھاری drawable | 3–20 ms | GPU Profiling |
| Thread | مرکزی تھریڈ کی بلاکنگ | 10–200 ms | Android Studio Profiler |
| GC | Garbage Collection | 5–15 ms | Memory Profiler |
| Rendering | GPU بوجھ | 10–50 ms | GPU Tracer، Xcode GPU |
Android میں، Jank کی تشخیص Perfetto سسٹم ٹریس سے شروع ہوتی ہے۔ Perfetto تمام تھریڈز، CPU، GPU اور شیڈیولر کی سرگرمی ریکارڈ کرتا ہے۔ Jank کا واضح اشارہ Choreographer.doFrame اور Choreographer.doCallbacks لائنیں ہیں: اگر دو متواتر doFrame کالوں کے درمیان وقفہ 16.6 ms سے زیادہ ہو تو فریم چھوٹ گیا ہے۔ Perfetto صحیح وجہ دکھاتا ہے — کون سا سسٹم کال، لاک یا GC تاخیر کا سبب بنا۔ Android Studio Profiler میں، CPU Profiler کے ذریعے اسی طرح کی فعالیت دستیاب ہے۔
پروڈکشن میں خودکار Jank کا پتہ لگانے کے لیے FrameMetricsAggregator استعمال ہوتا ہے — ایک API جو ہر فریم کے لیے اعدادوشمار جمع کرتا ہے اور سیشن کے مطابق جمع کرتا ہے۔ Android 12+ میں PerformanceHintManager آیا — سسٹم کو ہدف فریم ریٹ کے بارے میں اشارہ دینے کے لیے ایک API۔ اگر ایپ اشارہ کرتی ہے کہ یہ 120 FPS منظر نامے میں چل رہی ہے، تو سسٹم Jank کو روکنے کے لیے CPU/GPU فریکوئنسی بڑھا سکتا ہے۔ تمام چھوٹے ہوئے فریموں کی سادہ لاگنگ کے لیے، Choreographer.FrameCallback کو سبسکرائب کرنا کافی ہے۔
Kotlin کوڈ Choreographer.FrameCallback کو سبسکرائب کرتا ہے اور تاخیر کے دورانیے کے ساتھ ہر چھوٹے ہوئے فریم کو لاگ کرتا ہے۔ کال بیک ہر VSync پر بلایا جاتا ہے۔
class JankDetector {
private val frameBudget = 16_666_666L
private var previousFrameTime = 0L
private val callback =
Choreographer.FrameCallback { currentTime ->
if (previousFrameTime != 0L) {
val frameDuration =
currentTime - previousFrameTime
val skippedFrames =
(frameDuration / frameBudget) - 1
if (skippedFrames > 0) {
Log.w("Jank",
"Skipped $skippedFrames frames")
}
}
previousFrameTime = currentTime
Choreographer.getInstance()
.postFrameCallback(this)
}
fun start() {
Choreographer.getInstance()
.postFrameCallback(callback)
}
}
iOS میں، Jank کی تشخیص Core Animation ٹیمپلیٹ کے ساتھ Instruments کے ذریعے کی جاتی ہے۔ Instruments ریئل ٹائم FPS، آف اسکرین رینڈرز کی تعداد اور ہٹ ٹیسٹ دکھاتا ہے۔ iOS میں Jank کے اہم اشارے: Core Animation ٹائم لائن پر سرخ بار (فریم بجٹ سے تجاوز)، زیادہ Renderer قدر (آف اسکرین رینڈرنگ کی نشاندہی کرتی ہے) اور کم FPS۔ پروڈکشن مانیٹرنگ کے لیے، MetricKit MXAnimatoryMetric میٹرک کے ساتھ رپورٹیں جمع کرتا ہے، جس میں اوسط FPS، P50 اور P95 فریم ٹائم شامل ہے۔
iOS میں مقامی Jank تشخیص میں ٹائم اسٹیمپ اور targetTimestamp کی جانچ کے ساتھ CADisplayLink شامل ہے۔ اگر موجودہ ٹائم اسٹیمپ targetTimestamp سے نمایاں طور پر پیچھے ہے، تو ایک یا زیادہ فریم چھوٹ گئے ہیں۔ Apple کسٹم پروفائلنگ کے لیے os_signpost استعمال کرنے کی بھی سفارش کرتا ہے: فریم رینڈرنگ کے شروع اور آخر میں signpost-interval رکھیں اور Instruments میں دیکھیں کہ کون سے وقفے 16.6 ms سے زیادہ ہیں۔ SwiftUI میں، Jank تشخیص کے لیے UIView.invalidateIntrinsicContentSize استعمال ہوتا ہے — اس طریقہ کی بار بار کال غیر مستحکم Layout کی نشاندہی کرتی ہے۔
Swift کوڈ CADisplayLink کے ذریعے چھوٹے ہوئے فریموں کا پتہ لگاتا ہے۔ اگر ٹائم اسٹیمپ اور targetTimestamp کے درمیان فرق 16.6 ms سے زیادہ ہو تو Jank ریکارڈ کیا جاتا ہے۔
class JankMonitor {
private var displayLink: CADisplayLink?
private var totalJank = 0
func start() {
displayLink = CADisplayLink(
target: self,
selector: #selector(detectJank)
)
displayLink?.add(to: .current,
forMode: .common)
}
@objc
private func detectJank() {
guard let link = displayLink else { return }
let delay = link.targetTimestamp
- link.timestamp
if delay > 0.0167 {
totalJank += 1
}
}
}
Jank پروفائلنگ کے لیے، OS میں موجود بلٹ ان ٹولز اور تیسرے فریق کے SDK دونوں استعمال ہوتے ہیں۔ Android پر، اہم ٹول Perfetto ہے (جس نے Systrace کی جگہ لے لی)۔ Perfetto 30 سیکنڈ تک کے ٹریس ریکارڈ کر سکتا ہے اور ui.perfetto.dev ویب انٹرفیس کے ذریعے ان کا تجزیہ کر سکتا ہے۔ یہ Choreographer کی سرگرمی، رینڈرنگ تھریڈز (RenderThread) اور GPU کے ساتھ ایک درست ٹائم لائن دکھاتا ہے۔ GPU کے مسائل کے تفصیلی تجزیے کے لیے، AGI (Android GPU Inspector) استعمال ہوتا ہے، جو نہ صرف فریم ٹائم بلکہ مخصوص GPU بلاکس — شیڈرز، راسٹرائزر، ٹیکسچر یونٹ — پر بوجھ بھی دکھاتا ہے۔
iOS پر، متبادل Core Animation، Metal System Trace اور GPU Driver ٹیمپلیٹس کے ساتھ Instruments ہے۔ Core Animation FPS اور فریم ٹائم دکھاتا ہے، Metal System Trace ہر draw call تک GPU کام دکھاتا ہے۔ بوجھ کے تحت حقیقی آلات پر پروفائلنگ کے لیے، Firebase Performance (Screen Rendering میٹرک جمع کرتا ہے) اور Sentry (Jank پر اسٹیک ٹریس کیپچر کرتا ہے) استعمال ہوتے ہیں۔ نیا Android 15 Performance Hint API ڈویلپر کو سسٹم کو بتانے کی اجازت دیتا ہے کہ کون سے فریم اہم ہیں اور Jank قریب آنے پر سسٹم سے انتباہ حاصل کرتا ہے۔
Kotlin کوڈ سیشن کے دوران فریم کے اعدادوشمار جمع کرنے کے لیے FrameMetricsAggregator استعمال کرتا ہے۔ ایگریگیٹر کو روکنے کے بعد، چھوٹے ہوئے فریموں کی تعداد ظاہر ہوتی ہے۔
class JankAggregator(private val activity: Activity) {
private val aggregator = FrameMetricsAggregator()
fun startCollection() {
aggregator.add(activity.window)
}
fun stopAndReport() {
aggregator.remove()
val result = aggregator.getMetrics()
val totalFrames = result
?.get(FrameMetrics.TOTAL_DURATION)
?.size ?: 0
val jankFrames = result
?.get(FrameMetrics.TOTAL_DURATION)
?.count { it > 16_666_666L} ?: 0
Log.d("JankReport",
"Jank ratio: \${jankFrames * 100 / totalFrames}%")
}
}
Jank کو ختم کرنے کے لیے اس کی قسم کے مطابق تکنیکوں کے امتزاج کی ضرورت ہوتی ہے۔ Layout Jank کے لیے: گہرے درجہ بندی کو ConstraintLayout/Compose/SwiftUI سے بدلیں، merge ٹیگ استعمال کریں، اینیمیشنز میں requestLayout سے بچیں۔ Draw Jank کے لیے: 4x+ overdraw تلاش کرنے کے لیے Debug GPU Overdraw استعمال کریں، بھاری drawable کو ویکٹر گرافکس (VectorDrawable/PDF) سے بدلیں، ہارڈویئر لیئرز احتیاط سے استعمال کریں — یہ رینڈرنگ کو تیز کرتی ہیں لیکن زیادہ GPU میموری استعمال کرتی ہیں۔ Thread Jank کے لیے: تمام I/O آپریشنز، ڈیٹابیس کا کام اور Bitmap ڈی کوڈنگ کو بیک گراؤنڈ تھریڈز میں منتقل کریں، درست Dispatcher کے ساتھ Kotlin Coroutines یا Schedulers.io() کے ساتھ RxJava استعمال کریں۔
GC Jank کے لیے: onDraw() اور getView() میں مختص کرنا کم سے کم کریں، آبجیکٹ پول (ObjectPool) استعمال کریں، for-each کو indexed for سے بدلیں، Kotlin میں copy() کے ساتھ immutable data class احتیاط سے استعمال کریں — copy نیا آبجیکٹ بناتا ہے۔ IPC Jank کے لیے: App Startup کے ذریعے ContentProvider کو سست طریقے سے شروع کریں، Binder کالوں کو بیک گراؤنڈ تھریڈ میں منتقل کریں۔ Rendering Jank کے لیے: ساخت کا سائز زیادہ سے زیادہ اسکرین ریزولوشن تک کم کریں، ASTC یا ETC2 کمپریشن استعمال کریں، ضرورت سے زیادہ شیڈر کمپائلیشن سے بچیں (شیڈرز پہلے سے کمپائل کریں)۔ ایک جامع حل CI میں باقاعدہ Perfetto/Instruments پروفائلنگ اور Jank ریگریشنز کو ٹریک کرنا ہے۔
Kotlin کوڈ reportFullyDrawn کے بعد اسکرین پر ڈیٹا کی غیر مطابقت پذیر لوڈنگ کا مظاہرہ کرتا ہے، تاکہ بھاری کام پہلے فریم کو بلاک نہ کرے۔ کال بیک صارف کے انٹرفیس دیکھنے کے بعد بلایا جاتا ہے۔
class JankSafeLoader {
suspend fun loadAfterFirstFrame(
activity: Activity
) {
// اس بات کی ضمانت کہ پہلا فریم پہلے ہی رینڈر ہو چکا ہے
if (Build.VERSION.SDK_INT >= 29) {
activity.reportFullyDrawn()
}
// بھاری لوڈنگ — پہلے فریم کے بعد
withContext(Dispatchers.IO) {
val data = fetchHeavyData()
withContext(Dispatchers.Main) {
updateUI(data)
}
}
}
}
اکثر پوچھے گئے سوالات
Jank چھوٹے ہوئے رینڈرنگ فریم ہیں جو اینیمیشن میں نمایاں رکاوٹ یا جھٹکوں کے طور پر ظاہر ہوتے ہیں۔ یہ اس وقت ہوتا ہے جب فریم تیار کرنے کا وقت وقت کے بجٹ (60 FPS کے لیے 16.6 ms) سے تجاوز کر جاتا ہے۔
Layout Jank (بار بار requestLayout)، Draw Jank (overdraw)، Thread Jank (مرکزی تھریڈ کی بلاکنگ)، GC Jank (کوڑا کرکٹ جمع کرنا)، IPC Jank (Binder کالیں) اور Rendering Jank (بھاری شیڈرز)۔
سسٹم ٹریسنگ کے لیے Perfetto، فریم مرحلے کے تجزیے کے لیے GPU Profiling اور پروڈکشن مانیٹرنگ کے لیے FrameMetricsAggregator استعمال کریں۔ Android Studio میں — Deep Java Trace کے ساتھ CPU Profiler۔
Instruments کے ذریعے Core Animation یا Metal System Trace ٹیمپلیٹ کے ساتھ۔ پروڈکشن کے لیے — MXAnimatoryMetric کے ساتھ MetricKit۔ پروگرامی طور پر — ٹائم اسٹیمپ اور targetTimestamp کے درمیان فرق چیک کرنے والا CADisplayLink۔
Google کے مطابق، سکرول سیشنز کے 3% سے زیادہ Jank کی شرح (100 سکرول میں سے 3 میں رکاوٹ) منفی جائزوں میں 22% اضافے کا باعث بنتی ہے۔ ہدف کی شرح سکرول سیشنز کے 0.5% سے کم ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں