Bỏ qua tới nội dung
Performance· ·8 phút đọc

INP đo độ phản hồi tương tác (và cách giảm xuống dưới 200ms)

Nguyen Hien
INP đo độ phản hồi tương tác (và cách giảm xuống dưới 200ms)
Cỡ chữ

Khi bạn bấm một nút mà trang đứng hình nửa giây rồi mới phản ứng, đó chính là thứ mà chỉ số này bắt được. Khác với cảm giác “tải nhanh” lúc mở trang, độ phản hồi đo lúc người dùng thao tác — bấm, gõ, chạm — và đây là nơi nhiều website hiện đại thất bại vì gánh quá nhiều JavaScript.

INP đo cái gì

INP gom toàn bộ tương tác trong một lượt truy cập, rồi báo cáo độ trễ của tương tác chậm gần nhất với tương tác tệ nhất. Mỗi tương tác được chia thành ba phần:

  • Input delay (độ trễ đầu vào) — khoảng từ lúc bạn bấm tới lúc trình duyệt bắt đầu chạy hàm xử lý. Nếu luồng chính (main thread — luồng xử lý chính của trình duyệt) đang bận chạy script khác, phần này phình to.
  • Processing time (thời gian xử lý) — thời gian chạy hàm xử lý sự kiện (event handler).
  • Presentation delay (độ trễ hiển thị) — thời gian trình duyệt tính lại bố cục và vẽ khung hình mới ra màn hình.

Cộng ba phần lại là độ trễ một tương tác. INP của trang là con số đại diện cho tương tác chậm nhất mà người dùng gặp phải.

So do so sanh chi so FID do lan dau va INP do moi tuong tac
FID chỉ đo lần tương tác đầu, còn INP đo mọi tương tác trong cả phiên.

Ngưỡng tốt 200ms

Theo web.dev, mức phân loại như sau (đo ở phân vị 75 — p75, nghĩa là 75% tương tác phải đạt):

INPPhân loại
≤ 200msTốt (Good)
200–500msCần cải thiện
> 500msKém

INP là Core Web Vital khó đạt nhất hiện nay: nhiều phân tích 2026 ghi nhận một tỷ lệ lớn website vẫn trượt mốc 200ms, cao hơn hẳn LCP hay CLS.

Vì sao INP thay FID

FID (First Input Delay — độ trễ tương tác đầu tiên) chỉ đo tương tác đầu tiên, và chỉ đo phần input delay — không tính thời gian xử lý lẫn thời gian vẽ lại. Hệ quả: tới ~93% site đạt FID, khiến chỉ số này gần như không phân biệt được trang thực sự mượt với trang chỉ tải nhanh lúc đầu rồi đơ khi bạn bấm.

INP sửa đúng hai điểm yếu đó:

Khía cạnhFID (cũ)INP (hiện hành)
Phạm viChỉ tương tác đầu tiênMọi tương tác cả phiên
Đo gìChỉ input delayInput delay + xử lý + hiển thị
Độ khóDễ đạt (lỏng)Khó đạt (chặt)

Vì INP đo trọn vòng đời tương tác và bắt cả những lần bấm về sau, nó phản ánh trải nghiệm thật sát hơn nhiều. Google công bố lộ trình từ tháng 5/2023 và chính thức đổi vào 12/3/2024 — FID đã ngừng là Core Web Vital từ ngày đó.

Cách đo INP

Có hai loại số liệu, đừng nhầm:

  • Field (dữ liệu thực địa) — INP “thật” từ người dùng Chrome, lấy qua CrUX, PageSpeed Insights hoặc Search Console. Đây mới là con số Google dùng để đánh giá.
  • Lab (phòng thí nghiệm) — Lighthouse không cho ra INP trực tiếp vì cần tương tác thật. Proxy gần nhất trong lab là TBT (Total Blocking Time — tổng thời gian chặn). TBT cao thường kéo INP cao, nên cải thiện TBT là cách gián tiếp kéo INP về ngưỡng tốt; Web22 dùng góc nhìn này khi đo bằng Lighthouse trên chính web22.dev.

Để bắt tương tác chậm cụ thể, mở tab Performance của Chrome DevTools, ghi lại trong lúc bấm/gõ, rồi soi các “long task” (tác vụ dài — bất kỳ tác vụ chạy quá 50ms trên luồng chính).

Tối ưu INP — giảm gánh cho luồng chính

Mọi đòn bẩy INP đều quy về một việc: đừng để luồng chính bị khoá khi người dùng tương tác.

1. Chia nhỏ long task

Một hàm chạy liền 300ms sẽ chặn mọi tương tác trong 300ms đó. Hãy cắt công việc nặng thành nhiều mẩu, nhường luồng chính giữa các mẩu để trình duyệt kịp xử lý cú bấm. API mới scheduler.yield() làm việc này gọn nhất; nếu chưa hỗ trợ thì dùng cách kinh điển:

function yieldToMain() {
  return new Promise(resolve => setTimeout(resolve, 0));
}

async function chayViecNang(danhSach) {
  for (const item of danhSach) {
    xuLy(item);
    // nhuong luong chinh sau moi muc
    await yieldToMain();
  }
}

2. Vẽ trước, xử lý nền sau

Trong hàm xử lý sự kiện, chỉ làm phần cập nhật giao diện mà người dùng cần thấy ngay; phần nặng (lưu dữ liệu, gọi thống kê, tính toán) đẩy ra sau khung hình kế tiếp:

button.addEventListener('click', () => {
  capNhatGiaoDien();           // chay ngay, nguoi dung thay phan hoi
  setTimeout(() => {
    luuDuLieu();               // hoan lai, khong chan tuong tac
  }, 0);
});

3. Cắt bớt JavaScript không cần

JS càng ít, luồng chính càng rảnh. Bỏ script bên thứ ba không cần thiết, defer những gì không cần chạy sớm, và áp tách mã theo route (code splitting) để chỉ tải đúng phần đang dùng.

4. Tránh layout thrashing

Đừng đọc thuộc tính bố cục (như offsetHeight) ngay sau khi vừa đổi style — trình duyệt buộc phải tính lại bố cục đồng bộ, làm phần xử lý phình ra. Gom các thao tác đọc và ghi DOM tách bạch.

Câu hỏi thường gặp

INP khác TBT thế nào?

TBT đo trong lab lúc trang tải; INP đo ngoài thực địa suốt phiên người dùng. TBT là proxy dự báo INP — xem thêm TBT là tổng thời gian chặn luồng chính.

Còn cần quan tâm FID không?

Không. FID đã ngừng là Core Web Vital từ 12/3/2024; PageSpeed cũng bỏ FID. Hãy tối ưu theo INP.

INP bao nhiêu là đạt?

200ms hoặc thấp hơn ở phân vị 75. Trên 500ms là kém và cần xử lý sớm.

Nếu trang của bạn trượt mốc 200ms và bạn muốn người khác đo lại, gỡ rối long task rồi xác nhận bằng số liệu thực địa, Web22 nhận tối ưu Core Web Vitals theo hướng đo trước sửa sau.

Đọc tiếp

Bài viết
cùng chủ đề.

Tất cả bài viết