Time-to-Interactive (TTI) is a performance metric that measures the time from the start of page load to the moment when the main content becomes interactive. In mobile applications, TTI is considered one of the key UX indicators because the user cannot interact with the interface until UI initialization is complete. According to Google Web Dev, 2025, TTI should be less than 3.8 seconds for a good user experience on mobile devices.
Key Takeaways
Time-to-Interactive is a performance metric that captures the moment when a page or application is ready for full user interaction. In the web context, TTI is defined as the time from the start of navigation to the moment when three conditions are met: the page has displayed useful content (First Contentful Paint), the main thread has been idle for at least 5 seconds, and all event listeners are registered. In mobile applications, TTI is the time from Activity launch to complete UI initialization, when all states are loaded, animations are configured, and the user can tap any button without delay.
This metric is especially important for applications where the first interaction is critical — login screens, search, checkout. If TTI exceeds 5 seconds, users perceive the app as “frozen” and may close it. According to Google (Web Vitals Report, 2025), pages with TTI under 3.8 seconds show 24% more conversions than pages with TTI over 7 seconds. The difference is felt even at 500 ms — Amazon’s research shows a 1% revenue loss for every 100 ms of delay.
The TTI calculation algorithm is defined in the W3C specification and implemented in Lighthouse. The calculation starts with First Contentful Paint (FCP) — the moment when the browser renders the first pixel of content. The algorithm then looks for a “quiet window” — a 5-second period during which no task on the main thread exceeds 50 ms. TTI is set to the last task before this window. If no quiet window is found within 15 seconds, TTI is set to the time of the last long task. This algorithm ensures that TTI reflects actual readiness for interaction, not just the rendering moment.
In mobile applications (Android/iOS), there is no exact W3C specification equivalent, but the concept is the same. TTI can be measured by capturing a timestamp in onResume (launch start) and in the callback of the first frame when all async operations are complete. Firebase Performance allows you to set a custom trace with start and end of the user interactive session. For example, startTrace(“TTI”) in Application.onCreate and stopTrace() after all SDKs have been initialized and the first frame has been rendered.
Kotlin code demonstrates TTI measurement using Firebase Performance. The trace starts in Application.onCreate and stops after the first reportFullyDrawn.
class App : Application() {
private var ttiTrace: Trace? = null
override fun onCreate() {
super.onCreate()
ttiTrace = Firebase.performance
.newTrace("tti")
ttiTrace?.start()
}
fun stopTtiTrace() {
ttiTrace?.stop()
ttiTrace = null
}
}
In the Core Web Vitals ecosystem, there are several metrics, and TTI is often confused with First Contentful Paint (FCP) and Largest Contentful Paint (LCP). FCP is the time of the first pixel of content rendering, which does not guarantee interactivity. LCP is the rendering time of the largest content element (image, text block). TTI, however, measures not rendering but readiness for interaction. The difference is critical: FCP can be 1.2 seconds, but if the main thread is blocked by JS bundle loading, TTI can reach 8 seconds.
First Input Delay (FID) measures the delay between the user’s first action and the moment when the browser starts processing the event. FID is “interactivity quality,” while TTI is “time to interactivity.” If TTI shows how many seconds until the interface becomes responsive, FID shows how responsive it was. Good TTI is impossible without good FID, because if the main thread is blocked, TTI will be high and FID will delay any interaction. In mobile applications, the equivalent of FID is Touch Latency — the delay between touching the screen and the UI response.
| Metric | What it measures | Target value | Platform |
|---|---|---|---|
| FCP | First pixel of content | < 1.8 s | Web |
| LCP | Largest content element | < 2.5 s | Web |
| TTI | Readiness for interaction | < 3.8 s | Web + native |
| FID | First input delay | < 100 ms | Web |
In native mobile applications, the concept of TTI is not as standardized as on the web, but its importance is no less. On Android, TTI is the time from tapping the app icon to the moment when the UI is fully interactive: RecyclerView scrolls, buttons respond to taps, animations run smoothly. To measure TTI on Android, a combination of reportFullyDrawn (API 29+) and FrameMetricsAggregator is used. reportFullyDrawn is a call that the app makes when the developer considers the UI ready. The system captures this moment and includes it in the Android Vitals report.
On iOS, the equivalents of TTI are Time to First Frame and Time to Responsive. MetricKit collects launch time data broken down into phases — executable loading, framework initialization, first frame rendering. Apple recommends that Time to First Frame should not exceed 400 ms, and full interactivity should be achieved within 2 seconds. If the app shows a placeholder screen and then loads content, TTI is calculated not from the first frame but from the moment when the actual content is ready for interaction.
Kotlin code tracks the first interactive frame using FrameMetricsAggregator. The callback fires after the first user-initiated frame is complete.
class TtiTracker(private val activity: Activity) {
private val metrics = FrameMetricsAggregator()
private var startTime = 0L
fun onStart() {
startTime = System.nanoTime()
metrics.add(activity.window)
}
fun onFirstFrame() {
val ttiMs = (System.nanoTime() - startTime) / 1_000_000
Log.d("TTI", "Time to Interactive: $ttiMs ms")
metrics.reset()
}
}
Optimizing TTI involves three directions: reducing main thread workload, deferred loading of non-critical components, and progressive rendering. The first direction is minimizing synchronous operations: replacing SharedPreferences with DataStore, moving SDK initialization to a background thread, lazy loading Dagger/Hilt modules. The second is deferred loading: screens that are not visible at startup (bottom sheets, dialogs, tabs) should be initialized after the first frame. The third is progressive rendering: first show a skeleton screen, then load content in parts.
On Android, an effective method is using the App Startup library with ranked initializers. For example, the Firebase Analytics initializer can be made optional and delayed by 2 seconds after startup. On iOS, the equivalent is Initialization Dependencies with the lazy flag. For the web, key methods are code splitting, tree shaking, preload/preconnect for critical resources, and defer for non-blocking JS. Google Lighthouse provides specific recommendations: “Eliminate render-blocking resources” and “Defer offscreen images” directly affect TTI.
Example of bundle splitting in React Native using React.lazy and Suspense. The HeavyScreen component loads only when the user navigates to that screen, reducing the initial screen TTI.
import React, { lazy, Suspense } from 'react';
const HeavyScreen = lazy(() =>
import('./screens/HeavyScreen')
);
const App = () => (
<Suspense fallback={<Loading />}>
<HeavyScreen />
</Suspense>
);
Several tools are available for measuring TTI, varying by platform and depth of analysis. On the web, the primary tool is Lighthouse in Chrome DevTools. Lighthouse runs an audit and outputs TTI in milliseconds, along with specific recommendations for improvement. For continuous monitoring, PageSpeed Insights (Google) is used — it collects data from the Chrome User Experience Report (CrUX) from real users. In native apps, TTI is measured via Android Vitals (Google Play Console) and MetricKit (Apple).
For production monitoring, popular tools include Firebase Performance Monitoring (custom traces), Datadog RUM (Real User Monitoring), and Sentry Performance. These tools not only show TTI but also allow you to trace the correlation between TTI and business metrics — conversion, churn, session time. Recommended thresholds: < 3.8 s — good, 3.8–7 s — needs improvement, > 7 s — critical. For native apps, thresholds are stricter: < 2 s — good, 2–5 s — average, > 5 s — critical, as mobile app users are less tolerant of delays.
Example of Lighthouse CI configuration for automated TTI checking in a CI/CD pipeline. If the 3.8-second threshold is exceeded, the build is flagged with a warning.
// lighthouserc.js
module.exports = {
ci: {
assert: {
assertions: {
'interactive': ['warn', {
maxNumericValue: 3800
}],
'first-contentful-paint': ['error', {
maxNumericValue: 1800
}]
}
},
collect: {
startServerCommand: 'npm start',
url: ['http://localhost:3000'],
numberOfRuns: 3
}
}
};
Frequently Asked Questions
FCP (First Contentful Paint) captures the moment the first pixel of content is rendered. TTI is the moment when the UI is ready for interaction. The difference can be 3–5 seconds if the main thread is blocked.
For the web, the target TTI is under 3.8 seconds. For native mobile apps, the threshold is stricter — under 2 seconds. Values above 7 seconds require immediate optimization.
On Android, use reportFullyDrawn (API 29+) in combination with FrameMetricsAggregator. For production monitoring, integrate Firebase Performance with a custom trace “TTI”.
Yes, TTI indirectly affects SEO through Core Web Vitals. Google uses LCP, FID, and CLS as direct ranking factors, but TTI correlates with them and influences behavioral metrics (time on page, bounce rate).
Lighthouse, PageSpeed Insights, WebPageTest — for the web. Firebase Performance, Android Vitals, MetricKit — for native apps.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also