Tối ưu chỉ số INP nâng cao với Long Animation Frames API (LoAF): Giảm lag JS khi click nút

2026-07-30 12 phút đọc 0 lượt xemBởi Uwmee Software

Trong bộ chỉ số đo lường trải nghiệm người dùng Core Web Vitals của Google, chỉ số INP (Interaction to Next Paint) đã chính thức thay thế hoàn toàn chỉ số FID cũ. INP đánh giá độ nhạy và khả năng phản hồi giao diện của trang web trong suốt toàn bộ phiên truy cập của người dùng mỗi khi họ thực hiện các tương tác bấm nút, gõ bàn phím hay mở menu.

Một website có điểm tải trang ban đầu rất nhanh nhưng mỗi khi người dùng bấm vào nút "Thêm vào giỏ hàng" hay nút "Mở Menu" giao diện lại bị đơ giật 300ms thì vẫn bị Google đánh tụt điểm INP thảm hại. Bài viết này sẽ hướng dẫn bạn sử dụng công cụ cắt lớp mới nhất của Chrome: Long Animation Frames API (LoAF) để triệt tiêu các tác vụ JavaScript gây lag giao diện.

1. Chỉ số INP (Interaction to Next Paint) là gì? Tiêu chuẩn đánh giá 2026

INP đo lường khoảng thời gian từ khi người dùng thực hiện một tương tác (Click, Tap, Keydown) cho đến khi trình duyệt vẽ xong khung hình tiếp theo (Next Paint) trên màn hình.

Thang điểm đánh giá INP của Google:

  • Tốt (Good): INP <= 200 millisecond (ms).
  • Cần cải thiện (Needs Improvement): INP từ 200ms đến 500ms.
  • Kém (Poor): INP > 500ms.

Thời gian trễ INP gồm 3 thành phần cấu thành: Input Delay (Độ trễ chờ) + Processing Time (Thời gian chạy JS Event Handler) + Presentation Delay (Thời gian trình duyệt vẽ lại khung hình UI). Tham khảo bài viết cơ bản Chỉ số INP là gì và cách tối ưu cơ bản.

2. Long Animation Frames API (LoAF) là gì? Bước đột phá thay thế Long Tasks

Trước đây, các nhà phát triển sử dụng Long Tasks API để phát hiện các tác vụ JavaScript chạy quá 50ms. Tuy nhiên, Long Tasks có nhược điểm lớn: Nó chỉ báo tác vụ đó bị chậm chứ không chỉ ra được chính xác đoạn mã file JS nào, hàm (Function) nào hay thư viện nào đang gây ra đơ lag.

Long Animation Frames API (LoAF) giải quyết triệt để vấn đề này. LoAF theo dõi từng khung hình hiển thị (Render Frame) bị trễ trên 50ms và cung cấp báo cáo chi tiết đến tận tên file JS, tên hàm và vị trí dòng mã gây ra hiện tượng giật đơ (Unblocking UI)!

3. Đoạn mã JavaScript lắng nghe chỉ số LoAF trực tiếp trên Trình duyệt

Bạn có thể chèn đoạn mã PerformanceObserver này vào trang web để tự động ghi lại các khung hình bị giật lag khi người dùng bấm tương tác:

<script>
if ('PerformanceObserver' in window) {
  const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // Chỉ lọc các animation frame bị lag trên 100ms
      if (entry.duration > 100) {
        console.warn('[LoAF Alert] Phát hiện khung hình bị lag:', entry.duration, 'ms');
        entry.scripts.forEach((script) => {
          console.log('--- File JS gây lag:', script.invoker);
          console.log('--- Thời gian chạy JS:', script.executionDuration, 'ms');
          console.log('--- Tên hàm gây tắc nghẽn:', script.sourceFunctionName);
        });
      }
    }
  });
  // Đăng ký lắng nghe sự kiện long-animation-frame
  observer.observe({ type: 'long-animation-frame', buffered: true });
}
</script>

4. 4 Kỹ thuật tối ưu mã nguồn JavaScript xử lý dứt điểm lỗi INP

1. Chia nhỏ Long Tasks bằng requestIdleCallback hoặc yieldToMain

Nếu bạn có một tác vụ tính toán JavaScript nặng (Ví dụ: Lọc danh sách 5.000 sản phẩm), thay vì bắt luồng chính (Main Thread) chạy liên tục 300ms làm đóng băng giao diện, hãy nhường luồng chính cho trình duyệt vẽ giao diện bằng hàm ngắt yieldToMain:

// Hàm ngắt nhường luồng chính Main Thread cho UI
function yieldToMain() {
  return new Promise((resolve) => {
    setTimeout(resolve, 0);
  });
}

async function processLargeList(items) {
  for (let i = 0; i < items.length; i++) {
    doCalculation(items[i]);
    // Cứ sau 50 phần tử, ngắt nhường luồng cho trình duyệt vẽ UI 1 lần
    if (i % 50 === 0) {
      await yieldToMain();
    }
  }
}

2. Áp dụng kỹ thuật Optimistic Updates cho giao diện

Khi người dùng bấm nút "Thích" hoặc nút "Thêm vào giỏ hàng", hãy ngay lập tức cập nhật trạng thái icon trên giao diện (Render UI 0ms) trước khi gửi yêu cầu API ngầm về Server. Kỹ thuật này giúp thời gian Presentation Delay bằng 0. Xem bài TanStack Query v5 Optimistic Updates 0ms.

3. Trì hoãn các Script bên thứ 3 (Third-party Scripts)

Các script theo dõi như Google Tag Manager, Facebook Pixel, Chat Widget thường xuyên chiếm dụng luồng chính ngay khi người dùng bấm tương tác. Sử dụng chiến lược nạp lùi lazyOnload trong Next.js Script để giải phóng luồng chính. Read Cách trì hoãn Script bên thứ 3 cứu điểm PageSpeed.

4. Tránh lỗi Reflow / Layout Thrashing trong CSS & DOM

Tránh việc liên tục đọc thuộc tính kích thước DOM (như element.offsetHeight) ngay sau khi vừa thay đổi Style CSS trong cùng 1 vòng lặp. Điều này bắt trình duyệt phải tính toán lại bố cục toàn trang (Layout Thrashing) gây ra sụt giảm chỉ số CLS và INP. Đọc thêm tại Cách khắc phục lỗi dịch chuyển giao diện CLS.

Kết luận

Long Animation Frames API (LoAF) là chiếc kính hiển vi công nghệ giúp các lập trình viên soi thấu và tiêu diệt tận gốc những đoạn mã JavaScript đơ lag làm suy giảm chỉ số INP. Việc tối ưu hóa INP mượt mà < 200ms sẽ mang lại trải nghiệm người dùng tuyệt hảo và giúp website của bạn bứt phá vượt qua mọi đối thủ trên bảng xếp hạng Google.

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

Bạn cần giải pháp phần mềm chuyên nghiệp?

Uwmee Software cung cấp dịch vụ 12 tester Google Play & thiết kế website cao cấp giúp nâng tầm thương hiệu của bạn.