Jank একটি শব্দ যা পৃথক ফ্রেম মিস হওয়ার কারণে ইন্টারফেস অ্যানিমেশনে লক্ষণীয় ঝাঁকুনি বা “হিচাপি” বোঝায়। মোবাইল অ্যাপে, Jank ঘটে যখন ফ্রেম রেন্ডারিংয়ের সময় ডিসপ্লে রিফ্রেশ রেট দ্বারা নির্ধারিত বাজেট অতিক্রম করে। Android Developers, 2025 অনুসারে, Jank হল “ধীরগতি”র বিষয়গত অনুভূতির প্রধান কারণ — অ্যাপটি কার্যকরীভাবে নিখুঁত হতে পারে, কিন্তু ব্যবহারকারী অস্থির FPS-এর কারণে এটিকে ধীর বলে মনে করেন।
মূল বিষয়
Jank কম্পিউটার গ্রাফিক্সের একটি শব্দ যা একটি চাক্ষুষ ত্রুটি বোঝায় যেখানে অ্যানিমেশন মসৃণ চলনের পরিবর্তে ঝাঁকুনি দিয়ে চলে। মোবাইল ডেভেলপমেন্টে, Jank প্রতি একক সময়ে মিস করা ফ্রেমের (skipped frames) সংখ্যা হিসাবে পরিমাপ করা হয়। যদি সিস্টেম VSync-এর সময়ের মধ্যে একটি ফ্রেম প্রস্তুত করতে ব্যর্থ হয়, ডিসপ্লে পূর্ববর্তী ফ্রেমটি পুনরাবৃত্তি করে — 60 Hz-এ 16.6 ms-এর বিরতি ঘটে। একটি মিস ফ্রেম অলক্ষিত হতে পারে, কিন্তু পরপর 3–5টি মিস ফ্রেম 50–80 ms স্থায়ী “ঝাঁকুনি”র অনুভূতি তৈরি করে, যা ব্যবহারকারী স্পষ্টভাবে লক্ষ্য করেন।
Jank বিশেষ করে সেই অ্যানিমেশনগুলির জন্য গুরুত্বপূর্ণ যা ধ্রুব গতিতে চলতে হবে: ফিড স্ক্রোলিং, মেনু খোলার অ্যানিমেশন, প্যারালাক্স ইফেক্ট, পর্দার মধ্যে স্থানান্তর। 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: সিঙ্ক্রোনাস অপারেশনের কারণে main thread ব্লকিং — ফাইল লোডিং, main thread-এ ডাটাবেস অপারেশন, Bitmap ডিকোডিং।
চতুর্থ বিভাগ — GC Jank: ART/Dalvik বা Swift ARC-তে আবর্জনা সংগ্রহ (Garbage Collection)। যখন হিপে অনেক অবজেক্ট জমা হয়, GC 5–15 ms-এর Stop-The-World বিরতি শুরু করে। Android-এ, GC বিরতি প্রায়শই লুপে ঘন ঘন বরাদ্দের সময় ঘটে: onDraw()-এ অবজেক্ট তৈরি, অ্যাডাপ্টারে বরাদ্দ, অব্যবহৃত lambda এক্সপ্রেশন। পঞ্চম — IPC Jank: main thread-এ আন্তঃপ্রক্রিয়া যোগাযোগ (ContentProvider, Binder)। ষষ্ঠ — Rendering Jank: অনুপযুক্ত শেডার বা বড় আকারের টেক্সচারের কারণে ধীর GPU রেন্ডারিং।
| Jank-এর ধরন | কারণ | সাধারণ সময়কাল | সনাক্তকরণ টুল |
|---|---|---|---|
| Layout | requestLayout, relayout | 5–30 ms | Perfetto, Systrace |
| Draw | Overdraw, ভারী drawable | 3–20 ms | GPU Profiling |
| Thread | Main 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 সঠিক কারণ দেখায় — কোন system call, lock বা 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-এ stack trace ক্যাপচার করে) ব্যবহৃত হয়। নতুন 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) দিয়ে প্রতিস্থাপন করুন, hardware layers সতর্কতার সাথে ব্যবহার করুন — এগুলি রেন্ডারিং দ্রুত করে কিন্তু বেশি 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 (main thread ব্লকিং), 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন