App Hang and UI Freeze Monitoring Setup for Mobile App

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
App Hang and UI Freeze Monitoring Setup for Mobile App
Medium
from 4 hours to 2 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Setting Up App Hang / UI Freeze Monitoring for Mobile Apps

An app hang is not a crash. The app is alive, but doesn't respond to touches. Users see a frozen screen, tap the button again, then again — and leave. Crashlytics shows nothing, the user stays silent, and conversion drops.

iOS Watchdog terminates the process on hang > 4–8 seconds. Android generates ANR after > 5 seconds. But 200–500ms hangs don't trigger system events — they just kill UX.

Sources of Hangs

On iOS, the most common source of short freezes is a synchronous main thread call triggered by a UI event:

// Antipattern: decode large JSON on main thread
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as! ProductCell
    // If product.image is Data that needs decoding, this blocks main thread
    cell.imageView?.image = UIImage(data: product.imageData)
    return cell
}

UIImage(data:) synchronously decodes JPEG/PNG. On iPhone SE with 1900x1200 image — 30–80ms main thread block per cellForRowAt.

On Android, the main culprit in Compose screens is unnecessary recomposition in LazyColumn:

// Antipattern: unstable type in LazyColumn
@Composable
fun ProductList(products: List<Product>) { // List<> is not stable
    LazyColumn {
        items(products) { product ->
            ProductCard(product) // redraws on any parent change
        }
    }
}

Replacing List<Product> with ImmutableList<Product> (kotlinx.collections.immutable) or using @Stable annotation on data class eliminates extra recompositions.

Detection Tools

iOS — MetricKit Hang Diagnostics

func didReceive(_ payloads: [MXDiagnosticPayload]) {
    for payload in payloads {
        payload.hangDiagnostics?.forEach { hang in
            let duration = hang.hangDuration
            let callStack = hang.callStackTree

            // hang.hangDuration — MXAverage, not exact
            // Minimal MetricKit tracking: hang > 250ms
            print("Hang duration: \(duration.averageMeasurement)")
        }
    }
}

MetricKit delivers data with daily delay. For real-time, need a custom solution.

iOS — Sentry App Hang Detection

SentrySDK.start { options in
    options.dsn = "https://[email protected]/project"
    options.enableAppHangTracking = true
    options.appHangTimeoutInterval = 0.25 // 250ms — report threshold
}

Sentry runs a watchdog thread that pings the main thread every 100ms. If no response > appHangTimeoutInterval, it captures the stack via backtrace_thread and sends it as an Issue.

Android — Jetpack Janky Frames

// FrameMetricsAggregator from AndroidX
val frameMetrics = FrameMetricsAggregator(FrameMetricsAggregator.JANK_DATA)
frameMetrics.add(activity)

// Later:
val metrics = frameMetrics.metrics
metrics?.get(FrameMetricsAggregator.JANK_INDEX)?.let { jankArray ->
    val jankyFrames = jankArray.size
    // Count of frames > 16ms
}

Android — Android Profiler and Perfetto

These tools aren't used in production, but for local diagnostics they're invaluable. Android Profiler shows System Trace: where main thread is busy, which locks are waited, where GC pauses occur.

Perfetto with android.view.Choreographer track shows dropped frames by screen.

Monitoring Setup in Datadog

// Long Tasks tracking in Datadog RUM
RUM.enable(with: RUM.Configuration(
    applicationID: "your-rum-app-id",
    longTaskThreshold: 0.1 // 100ms — anything longer is Long Task
))

In Datadog dashboard, build a widget:

count:rum.long_task{env:production,service:ios-app}
group_by: @view.name
visualize_as: top_list

This shows which screens have the most Long Tasks — and that's where you dig deeper.

What We Do

  • Connect Sentry enableAppHangTracking with 250ms threshold (iOS)
  • Configure MetricKit subscriber for daily diagnostics
  • Enable Datadog RUM Long Task tracking with 100ms threshold
  • On Android, set up FrameMetricsAggregator for key Activities
  • Build dashboard by screens with most Long Tasks
  • Analyze stack traces and identify specific culprits

Timeline

Basic setup via Sentry and Datadog: 4–8 hours. Full diagnostics with MetricKit and custom per-screen metrics: 1–2 days. Pricing is calculated individually.