INP: trang “ì” khi bấm, đo ở đâu và sửa JavaScript nào trước
INP (Interaction to Next Paint) đo khoảng thời gian từ lúc người dùng bấm, chạm hay gõ tới lúc màn hình đổi theo. Dưới 200 mili giây là tốt. Thủ phạm hầu như luôn là JavaScript chạy dài chiếm luồng chính: widget chat, pixel quảng cáo, thư viện giao diện nặng.

Bạn bấm nút “Thêm vào giỏ”, nửa giây sau mới thấy gì đó đổi. Bạn bấm mở menu trên điện thoại, không thấy phản ứng, bấm lần nữa, menu mở rồi đóng luôn. Cảm giác “ì” này có tên chỉ số: INP (Interaction to Next Paint), đo độ trễ từ lúc người dùng tương tác tới lúc trình duyệt vẽ được khung hình tiếp theo. Từ tháng 3/2024, INP thay FID trong bộ Core Web Vitals của Google. Khác FID chỉ đo lần tương tác đầu tiên, INP xét gần như mọi lần bấm, chạm, gõ phím trong suốt thời gian người dùng ở trang, rồi lấy giá trị gần tệ nhất. Vì vậy trang “tải nhanh” vẫn có thể có INP xấu nếu nó ì khi dùng.
Ngưỡng và nơi đo
| INP | Đánh giá |
|---|---|
| ≤ 200 ms | Tốt |
| 200–500 ms | Cần cải thiện |
| > 500 ms | Kém |
Ngưỡng áp cho phân vị thứ 75 của các lượt truy cập thật, nghĩa là 75% lượt truy cập phải đạt mức đó. Có hai loại số liệu cần phân biệt:
- Dữ liệu thực địa (từ báo cáo trải nghiệm người dùng Chrome, CrUX): số đo từ người dùng thật trong 28 ngày. Hiện ở phần đầu PageSpeed Insights và trong báo cáo Chỉ số thiết yếu về trang web của Search Console. Đây là số Google dùng.
- Dữ liệu thử nghiệm (Lighthouse): một lần tải trong môi trường giả lập. Lighthouse không đo được INP vì không có ai bấm; chỉ số gần nhất là Total Blocking Time (TBT), cho biết luồng chính bị chiếm bao lâu lúc tải.
Site ít lượt truy cập có thể không đủ dữ liệu thực địa; khi đó dùng TBT làm chỉ báo và tự đo bằng tay như hướng dẫn bên dưới.
Vì sao trang ì: luồng chính bị chiếm
Trình duyệt có một luồng chính lo cả việc chạy JavaScript, tính bố cục và vẽ màn hình. Khi bạn bấm, sự kiện phải chờ luồng chính rảnh mới được xử lý. Nếu lúc đó một đoạn JavaScript đang chạy 400 mili giây (một “tác vụ dài”), lần bấm của bạn phải xếp hàng. INP gồm ba phần cộng lại:
- Độ trễ đầu vào: thời gian chờ luồng chính rảnh.
- Thời gian xử lý: mã xử lý sự kiện bấm chạy bao lâu.
- Độ trễ hiển thị: thời gian tính lại bố cục và vẽ sau khi xử lý xong.
Phần lớn site Việt bị nặng ở phần 1: lúc người dùng bấm, luồng chính đang bận chạy kịch bản của bên thứ ba.
Thủ phạm hay gặp trên site Việt
| Thủ phạm | Vì sao nặng | Hướng xử lý |
|---|---|---|
| Widget chat (Messenger, Zalo, chat tổng đài nhúng) | Tải cả ứng dụng nhỏ vào trang, chạy liên tục | Chỉ tải khi người dùng bấm vào biểu tượng chat (hiện một nút giả nhẹ trước) |
| Nhiều pixel quảng cáo (Facebook, TikTok, Google, các mạng quảng cáo) | Mỗi pixel nghe mọi lần bấm để ghi sự kiện | Gom về một trình quản lý thẻ, bỏ pixel không còn chạy quảng cáo |
| Thanh trượt ảnh, hiệu ứng cuộn, bộ đếm ngược | Chạy liên tục theo khung hình | Bỏ bớt; dùng CSS thay JavaScript cho hiệu ứng đơn giản |
| Page builder trên WordPress | Thêm nhiều tầng thẻ lồng nhau và kịch bản cho mọi khối | Tắt khối không dùng, giảm số tầng; trang quan trọng dựng gọn hơn |
| Bộ lọc sản phẩm tính lại cả trang mỗi lần bấm | Xử lý nghìn phần tử trong một tác vụ | Chia nhỏ việc, cập nhật giao diện trước rồi tính sau |
| Nút “Thêm vào giỏ” gửi nhiều sự kiện đo lường đồng bộ | Phần xử lý dài ngay trong sự kiện bấm | Đổi giao diện ngay, gửi sự kiện đo sau |
Tự đo INP trên trang của mình
- Mở Chrome trên máy tính, công cụ nhà phát triển, tab Performance. Bật giới hạn CPU chậm 4 lần để giống điện thoại tầm trung.
- Bấm ghi, rồi thao tác như người dùng: mở menu, bấm chọn màu, thêm vào giỏ, mở hỏi đáp.
- Dừng ghi. Mục Interactions liệt kê từng lần tương tác với thời gian; tác vụ dài được đánh dấu tam giác đỏ.
- Bấm vào tác vụ dài để xem kịch bản nào gây ra: tên tệp cho biết là của bạn hay của bên thứ ba.
Thêm cách khác: tiện ích Web Vitals của Chrome hiện INP mỗi lần bạn bấm, tiện để thử nhanh trên nhiều trang.

Đọc báo cáo trong Search Console theo nhóm trang
Báo cáo Chỉ số thiết yếu về trang web trong Search Console không liệt kê từng trang mà gom các địa chỉ giống nhau thành nhóm, rồi gắn trạng thái Tốt, Cần cải thiện hoặc Kém cho cả nhóm. Mỗi nhóm có một địa chỉ ví dụ và giá trị INP tổng hợp. Cách đọc hiệu quả:
- Tách báo cáo điện thoại và máy tính. Ở Việt Nam, điện thoại thường chiếm phần lớn lượt truy cập và cũng là nơi INP tệ nhất vì máy yếu hơn.
- Xem nhóm nào có nhiều địa chỉ nhất trong trạng thái Kém. Thường là một loại trang: toàn bộ trang sản phẩm, hoặc toàn bộ bài viết có khung bình luận.
- Mở địa chỉ ví dụ, đo bằng tay theo các bước ở trên, tìm kịch bản chung của loại trang đó.
- Sửa ở tệp mẫu (template) của loại trang, không sửa từng trang một.
- Sau khi sửa, bấm “Xác thực bản sửa lỗi” trong báo cáo. Google theo dõi 28 ngày dữ liệu mới rồi báo kết quả.
Một chi tiết hay gây nhầm: trang chủ có thể tốt trong khi trang sản phẩm kém, vì trang sản phẩm có bộ chọn biến thể, khung đánh giá, nút mua nổi. Đo trang chủ rồi kết luận “site nhanh” là bỏ sót đúng chỗ khách bấm nhiều nhất. Shop online nên ưu tiên ba loại trang: sản phẩm, danh mục có bộ lọc, giỏ hàng.
Cách sửa theo thứ tự đáng làm
1. Bỏ bớt trước khi tối ưu
Liệt kê mọi kịch bản bên thứ ba trên trang. Hỏi từng cái: còn ai dùng số liệu này không. Pixel của chiến dịch đã dừng từ năm ngoái, công cụ ghi lại phiên người dùng không ai xem, hai công cụ đo lường cùng đo một thứ. Bỏ một kịch bản không cần thiết hiệu quả hơn mọi kỹ thuật tối ưu.
2. Hoãn những gì không cần lúc đầu
Widget chat, khung bình luận, video nhúng: tải khi người dùng tỏ ý cần (bấm vào, cuộn tới). Một nút chat giả bằng ảnh và CSS nhẹ hơn hàng trăm lần so với widget thật.
3. Chia nhỏ tác vụ dài trong mã của mình
Trong mã xử lý sự kiện, cập nhật giao diện trước (đổi trạng thái nút, hiện biểu tượng đang xử lý), rồi nhường luồng chính trước khi làm việc nặng:
nut.addEventListener('click', async () => {
nut.classList.add('dang-them'); // phản hồi ngay
await new Promise(r => setTimeout(r, 0)); // nhường luồng chính để vẽ
await themVaoGio(maSanPham); // việc nặng làm sau
guiSuKienDoLuong('them_vao_gio');
});
4. Giảm kích thước DOM
Trang có hàng chục nghìn phần tử HTML làm mọi lần tính lại bố cục chậm. Trang danh mục hiện 200 sản phẩm một lúc, menu lớn có hàng trăm mục ẩn, page builder lồng mười tầng thẻ div: đều làm độ trễ hiển thị tăng. Chấm điểm SEO báo dung lượng HTML lớn bất thường, một dấu hiệu sớm của DOM nặng.
INP ảnh hưởng thứ hạng bao nhiêu
Core Web Vitals là một phần của tín hiệu trải nghiệm trang, và Google nói rõ nó là tín hiệu nhỏ so với mức liên quan của nội dung. Trang INP kém mà nội dung tốt nhất vẫn có thể đứng đầu. Lý do thật để sửa INP nằm ở chuyển đổi: người dùng bấm “Đặt hàng” mà không thấy gì xảy ra sẽ bấm lại, bỏ đi, hoặc đặt trùng đơn. Với shop online, mỗi trăm mili giây ì ở nút mua hàng là tiền. Xem bức tranh chung ở bài TTFB và Core Web Vitals.
Checklist INP
- Xem INP thực địa trong Search Console hoặc PageSpeed Insights, theo nhóm trang.
- Ghi hồ sơ Performance với CPU chậm 4 lần, thao tác như người dùng.
- Liệt kê kịch bản bên thứ ba, bỏ cái không dùng.
- Hoãn widget chat, bình luận, video tới khi người dùng cần.
- Nút quan trọng phản hồi giao diện ngay, việc nặng làm sau.
- Giảm số phần tử HTML trên trang danh mục và trang dựng bằng page builder.
- Đo lại sau 28 ngày với dữ liệu thực địa.
Hỏi đáp
INP khác FID thế nào?
FID chỉ đo độ trễ đầu vào của lần tương tác đầu tiên. INP đo toàn bộ thời gian từ lúc tương tác tới lúc màn hình đổi, xét gần như mọi lần tương tác trong lượt xem trang. INP đã thay FID trong Core Web Vitals từ tháng 3 năm 2024.
Vì sao PageSpeed Insights không có số INP cho trang của mình?
INP chỉ đo được từ người dùng thật. Trang ít lượt truy cập không đủ dữ liệu trong báo cáo Chrome. Khi đó xem Total Blocking Time trong phần thử nghiệm làm chỉ báo gần đúng.
Widget chat Zalo, Messenger có làm INP xấu không?
Thường có, vì chúng tải và chạy nhiều JavaScript. Cách phổ biến là hiện một nút chat nhẹ trước, chỉ tải widget thật khi người dùng bấm vào.
INP kém có làm tụt hạng không?
Ảnh hưởng thứ hạng nhỏ. Tác động lớn hơn nằm ở trải nghiệm và chuyển đổi: nút mua hàng phản hồi chậm làm người dùng bỏ đi hoặc bấm trùng.
Đọc tiếp

TTFB và Core Web Vitals: con số nào ảnh hưởng thứ hạng, con số nào chỉ để báo cáo
Google dùng ba chỉ số Core Web Vitals đo trên người dùng thật (LCP ≤2,5s, INP ≤200ms, CLS ≤0,1 ở phân vị 75), không dùng điểm Lighthouse. T…

CLS: trang nhảy khi đang đọc, năm nguyên nhân và cách giữ chỗ cho từng thứ
CLS (Cumulative Layout Shift) đo mức nội dung trên trang bị xô lệch bất ngờ khi đang hiển thị. Dưới 0,1 là tốt. Cách sửa chung cho mọi nguy…

WordPress chậm: đo trước khi cài thêm plugin tăng tốc, và năm thủ phạm hay gặp
Phần lớn site WordPress chậm vì máy chủ mất quá lâu để dựng trang (TTFB cao), không phải vì ảnh hay CSS. Đo TTFB trước; nếu cao thì tìm ngu…

Tối ưu ảnh cho tốc độ: WebP, AVIF, srcset và lazy loading đúng chỗ
Ảnh là thứ nặng nhất trên phần lớn trang web Việt, và cũng dễ sửa nhất. Đổi sang WebP hoặc AVIF, phục vụ đúng kích thước theo màn hình, kha…