Time-to-Interactive (TTI) là một chỉ số hiệu suất đo thời gian từ khi bắt đầu tải trang đến thời điểm nội dung chính trở nên tương tác được. Trong các ứng dụng di động, TTI được coi là một trong những chỉ số UX chính vì người dùng không thể tương tác với giao diện cho đến khi quá trình khởi tạo UI hoàn tất. Theo Google Web Dev, 2025, TTI phải dưới 3,8 giây để có trải nghiệm người dùng tốt trên thiết bị di động.
Những điểm chính
Time-to-Interactive là một chỉ số hiệu suất xác định thời điểm trang hoặc ứng dụng sẵn sàng cho tương tác đầy đủ với người dùng. Trong bối cảnh web, TTI được định nghĩa là thời gian từ khi bắt đầu điều hướng đến thời điểm ba điều kiện được đáp ứng: trang đã hiển thị nội dung hữu ích (First Contentful Paint), luồng chính đã nhàn rỗi trong ít nhất 5 giây và tất cả trình lắng nghe sự kiện đã được đăng ký. Trong ứng dụng di động, TTI là thời gian từ khi khởi chạy Activity đến khi hoàn tất khởi tạo UI, khi tất cả trạng thái được tải, hoạt ảnh được cấu hình và người dùng có thể chạm vào bất kỳ nút nào mà không bị chậm trễ.
Chỉ số này đặc biệt quan trọng đối với các ứng dụng nơi tương tác đầu tiên rất quan trọng — màn hình đăng nhập, tìm kiếm, thanh toán. Nếu TTI vượt quá 5 giây, người dùng coi ứng dụng như bị “đơ” và có thể đóng nó. Theo Google (Web Vitals Report, 2025), các trang có TTI dưới 3,8 giây cho thấy tỷ lệ chuyển đổi cao hơn 24% so với các trang có TTI trên 7 giây. Sự khác biệt có thể cảm nhận được ở mức 500 ms — nghiên cứu của Amazon cho thấy mất 1% doanh thu cho mỗi 100 ms chậm trễ.
Thuật toán tính TTI được định nghĩa trong đặc tả W3C và được triển khai trong Lighthouse. Tính toán bắt đầu với First Contentful Paint (FCP) — thời điểm trình duyệt render pixel nội dung đầu tiên. Sau đó, thuật toán tìm “cửa sổ im lặng” — khoảng thời gian 5 giây trong đó không có tác vụ nào trên luồng chính vượt quá 50 ms. TTI được đặt ở tác vụ cuối cùng trước cửa sổ này. Nếu không tìm thấy cửa sổ im lặng trong vòng 15 giây, TTI được đặt bằng thời gian của tác vụ dài cuối cùng. Thuật toán này đảm bảo TTI phản ánh trạng thái sẵn sàng thực sự để tương tác, không chỉ là thời điểm render.
Trong ứng dụng di động (Android/iOS), không có tương đương chính xác với đặc tả W3C, nhưng khái niệm là giống nhau. TTI có thể được đo bằng cách ghi lại dấu thời gian trong onResume (bắt đầu khởi chạy) và trong callback của khung hình đầu tiên khi tất cả các hoạt động không đồng bộ hoàn tất. Firebase Performance cho phép bạn đặt trace tùy chỉnh với điểm bắt đầu và kết thúc của phiên tương tác người dùng. Ví dụ: startTrace(“TTI”) trong Application.onCreate và stopTrace() sau khi tất cả SDK được khởi tạo và khung hình đầu tiên được render.
Mã Kotlin minh họa đo TTI bằng Firebase Performance. Trace bắt đầu trong Application.onCreate và dừng sau reportFullyDrawn đầu tiên.
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
}
}
Trong hệ sinh thái Core Web Vitals, có một số chỉ số và TTI thường bị nhầm lẫn với First Contentful Paint (FCP) và Largest Contentful Paint (LCP). FCP là thời gian render pixel nội dung đầu tiên, không đảm bảo tính tương tác. LCP là thời gian render phần tử nội dung lớn nhất (hình ảnh, khối văn bản). TTI, tuy nhiên, không đo việc render mà đo sự sẵn sàng tương tác. Sự khác biệt rất quan trọng: FCP có thể là 1,2 giây, nhưng nếu luồng chính bị chặn bởi việc tải bundle JS, TTI có thể lên tới 8 giây.
First Input Delay (FID) đo độ trễ giữa hành động đầu tiên của người dùng và thời điểm trình duyệt bắt đầu xử lý sự kiện. FID là “chất lượng tương tác”, trong khi TTI là “thời gian đến tương tác”. Nếu TTI cho thấy sau bao nhiêu giây giao diện phản hồi, thì FID cho thấy mức độ phản hồi của nó. TTI tốt là không thể nếu không có FID tốt, bởi vì nếu luồng chính bị chặn, TTI sẽ cao và FID sẽ làm trì hoãn mọi tương tác. Trong ứng dụng di động, tương đương của FID là Touch Latency — độ trễ giữa chạm màn hình và phản hồi của UI.
| Chỉ số | Đo lường gì | Giá trị mục tiêu | Nền tảng |
|---|---|---|---|
| FCP | Pixel nội dung đầu tiên | < 1,8 giây | Web |
| LCP | Phần tử nội dung lớn nhất | < 2,5 giây | Web |
| TTI | Sẵn sàng tương tác | < 3,8 giây | Web + native |
| FID | Độ trễ đầu vào đầu tiên | < 100 ms | Web |
Trong ứng dụng di động native, khái niệm TTI không được chuẩn hóa như trên web, nhưng tầm quan trọng của nó không hề thấp hơn. Trên Android, TTI là thời gian từ khi chạm vào biểu tượng ứng dụng đến thời điểm UI hoàn toàn tương tác: RecyclerView cuộn được, các nút phản hồi khi chạm, hoạt ảnh chạy mượt mà. Để đo TTI trên Android, sử dụng kết hợp reportFullyDrawn (API 29+) và FrameMetricsAggregator. reportFullyDrawn là một lệnh gọi mà ứng dụng thực hiện khi nhà phát triển cho rằng UI đã sẵn sàng. Hệ thống ghi lại thời điểm này và đưa nó vào báo cáo Android Vitals.
Trên iOS, tương đương của TTI là Time to First Frame và Time to Responsive. MetricKit thu thập dữ liệu thời gian khởi động được chia thành các giai đoạn — tải tệp thực thi, khởi tạo framework, render khung hình đầu tiên. Apple khuyến nghị Time to First Frame không vượt quá 400 ms và khả năng tương tác đầy đủ đạt được trong vòng 2 giây. Nếu ứng dụng hiển thị màn hình chờ và sau đó tải nội dung, TTI được tính không phải từ khung hình đầu tiên mà từ thời điểm nội dung thực sự sẵn sàng tương tác.
Mã Kotlin theo dõi khung hình tương tác đầu tiên bằng FrameMetricsAggregator. Callback được kích hoạt sau khi khung hình đầu tiên do người dùng khởi tạo hoàn tất.
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()
}
}
Tối ưu hóa TTI bao gồm ba hướng: giảm khối lượng công việc trên luồng chính, tải trì hoãn các thành phần không quan trọng và render dần dần. Hướng đầu tiên là giảm thiểu các hoạt động đồng bộ: thay thế SharedPreferences bằng DataStore, chuyển khởi tạo SDK sang luồng nền, tải lười các mô-đun Dagger/Hilt. Hướng thứ hai là tải trì hoãn: các màn hình không hiển thị khi khởi động (bottom sheet, hộp thoại, tab) nên được khởi tạo sau khung hình đầu tiên. Hướng thứ ba là render dần dần: đầu tiên hiển thị màn hình skeleton, sau đó tải nội dung theo từng phần.
Trên Android, một phương pháp hiệu quả là sử dụng thư viện App Startup với các bộ khởi tạo được xếp hạng. Ví dụ, bộ khởi tạo Firebase Analytics có thể được đặt thành tùy chọn và trì hoãn 2 giây sau khi khởi động. Trên iOS, tương đương là Initialization Dependencies với cờ lazy. Đối với web, các phương pháp chính là code splitting, tree shaking, preload/preconnect cho tài nguyên quan trọng và defer cho JS không chặn. Google Lighthouse đưa ra các khuyến nghị cụ thể: “Eliminate render-blocking resources” và “Defer offscreen images” ảnh hưởng trực tiếp đến TTI.
Ví dụ về chia bundle trong React Native sử dụng React.lazy và Suspense. Thành phần HeavyScreen chỉ được tải khi người dùng điều hướng đến màn hình đó, giảm TTI của màn hình ban đầu.
import React, { lazy, Suspense } from 'react';
const HeavyScreen = lazy(() =>
import('./screens/HeavyScreen')
);
const App = () => (
<Suspense fallback={<Loading />}>
<HeavyScreen />
</Suspense>
);
Có một số công cụ để đo TTI, khác nhau theo nền tảng và độ sâu phân tích. Trên web, công cụ chính là Lighthouse trong Chrome DevTools. Lighthouse chạy kiểm tra và xuất TTI tính bằng mili giây, cùng với các khuyến nghị cụ thể để cải thiện. Để giám sát liên tục, PageSpeed Insights (Google) được sử dụng — nó thu thập dữ liệu từ Chrome User Experience Report (CrUX) từ người dùng thực. Trong ứng dụng native, TTI được đo qua Android Vitals (Google Play Console) và MetricKit (Apple).
Để giám sát sản xuất, các công cụ phổ biến bao gồm Firebase Performance Monitoring (trace tùy chỉnh), Datadog RUM (Giám sát người dùng thực) và Sentry Performance. Các công cụ này không chỉ hiển thị TTI mà còn cho phép theo dõi mối tương quan giữa TTI và các chỉ số kinh doanh — chuyển đổi, tỷ lệ rời bỏ, thời gian phiên. Ngưỡng khuyến nghị: < 3,8 giây — tốt, 3,8–7 giây — cần cải thiện, > 7 giây — nghiêm trọng. Đối với ứng dụng native, ngưỡng chặt chẽ hơn: < 2 giây — tốt, 2–5 giây — trung bình, > 5 giây — nghiêm trọng, vì người dùng ứng dụng di động ít chịu được sự chậm trễ hơn.
Ví dụ cấu hình Lighthouse CI để tự động kiểm tra TTI trong đường ống CI/CD. Khi vượt quá ngưỡng 3,8 giây, bản dựng được đánh dấu cảnh báo.
// 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
}
}
};
Câu hỏi thường gặp
FCP (First Contentful Paint) ghi lại thời điểm pixel nội dung đầu tiên được render. TTI là thời điểm UI sẵn sàng tương tác. Sự khác biệt có thể là 3–5 giây nếu luồng chính bị chặn.
Đối với web, giá trị mục tiêu của TTI là dưới 3,8 giây. Đối với ứng dụng di động native, ngưỡng chặt hơn — dưới 2 giây. Giá trị trên 7 giây cần tối ưu hóa ngay lập tức.
Trên Android, sử dụng reportFullyDrawn (API 29+) kết hợp với FrameMetricsAggregator. Để giám sát sản xuất, tích hợp Firebase Performance với trace tùy chỉnh “TTI”.
Có, TTI ảnh hưởng gián tiếp đến SEO thông qua Core Web Vitals. Google sử dụng LCP, FID và CLS làm yếu tố xếp hạng trực tiếp, nhưng TTI tương quan với chúng và ảnh hưởng đến các chỉ số hành vi (thời gian trên trang, tỷ lệ thoát).
Lighthouse, PageSpeed Insights, WebPageTest — cho web. Firebase Performance, Android Vitals, MetricKit — cho ứng dụng native.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm