Chỉ số tuỳ chỉnh

Các chỉ số tập trung vào người dùng mang lại rất nhiều giá trị mà bạn có thể đo lường trên mọi trang web trên toàn cầu. Các chỉ số này cho phép bạn:

  • Hiểu cách người dùng thực trải nghiệm web nói chung.
  • So sánh trang web của bạn với trang web của đối thủ cạnh tranh.
  • Theo dõi dữ liệu hữu ích và hữu ích trong các công cụ phân tích mà không cần viết mã tuỳ chỉnh.

Các chỉ số chung cung cấp một đường cơ sở hữu ích, nhưng trong nhiều trường hợp, bạn cần đo lường nhiều hơn ngoài những chỉ số này để nắm bắt được toàn bộ trải nghiệm cho trang web cụ thể của mình.

Chỉ số tuỳ chỉnh cho phép bạn đo lường các khía cạnh về trải nghiệm trên trang web mà chỉ có thể áp dụng cho trang web của bạn, chẳng hạn như:

  • Khoảng thời gian để một ứng dụng trang đơn (SPA) chuyển đổi từ một "trang" sang một "trang" khác.
  • Khoảng thời gian mà một trang hiển thị dữ liệu được tìm nạp từ cơ sở dữ liệu đối với người dùng đã đăng nhập.
  • Thời gian cần thiết để một ứng dụng hiển thị phía máy chủ (SSR) hydrat hoá.
  • Tỷ lệ truy cập vào bộ nhớ đệm cho các tài nguyên do khách truy cập cũ tải.
  • Độ trễ của các sự kiện nhấp chuột hoặc bàn phím trong một trò chơi.

Các API dùng để đo lường chỉ số tuỳ chỉnh

Trước đây, các nhà phát triển web chưa có nhiều API cấp thấp để đo lường hiệu suất. Vì vậy, họ phải sử dụng phương thức tấn công để đo lường xem một trang web có hoạt động hiệu quả hay không.

Ví dụ: bạn có thể xác định xem luồng chính có bị chặn do các tác vụ JavaScript chạy trong thời gian dài hay không bằng cách chạy vòng lặp requestAnimationFrame và tính toán delta giữa mỗi khung. Nếu delta dài hơn đáng kể so với tốc độ khung hình của màn hình, bạn có thể báo cáo việc đó dưới dạng một tác vụ dài. Tuy nhiên, những kiểu tấn công như vậy không được khuyến khích vì chúng thực sự tự ảnh hưởng đến hiệu suất (chẳng hạn như làm tiêu hao pin).

Nguyên tắc đầu tiên để đo lường hiệu suất hiệu quả là đảm bảo các kỹ thuật đo lường hiệu suất của bạn không gây ra các vấn đề về hiệu suất. Vì vậy, đối với mọi chỉ số tuỳ chỉnh mà bạn đo lường trên trang web của mình, bạn nên sử dụng một trong các API sau nếu có thể.

Performance Observer API (API Trình quan sát hiệu suất)

Hỗ trợ trình duyệt

  • 52
  • 79
  • 57
  • 11

Nguồn

Performance Observer API là cơ chế thu thập và hiển thị dữ liệu từ tất cả các API hiệu suất khác được thảo luận trên trang này. Việc hiểu rõ điều quan trọng là phải có được dữ liệu chất lượng cao.

Bạn có thể sử dụng PerformanceObserver để đăng ký nhận các sự kiện liên quan đến hiệu suất theo cách thụ động. Điều này cho phép các lệnh gọi lại API kích hoạt trong thời gian không hoạt động, nghĩa là các lệnh gọi lại này thường sẽ không ảnh hưởng đến hiệu suất của trang.

Để tạo PerformanceObserver, hãy truyền lệnh gọi lại đó để chạy bất cứ khi nào các mục nhập hiệu suất mới được gửi đi. Sau đó, bạn cho trình quan sát biết loại mục nhập nào cần theo dõi bằng cách sử dụng phương thức observe():

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // Log the entry and all associated details.
      console.log(entry.toJSON());
    }
  });

  po.observe({type: 'some-entry-type'});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

Các phần sau liệt kê tất cả các loại mục nhập hiện có để quan sát. Tuy nhiên, trong các trình duyệt mới hơn, bạn có thể kiểm tra xem những loại mục nhập nào có sẵn thông qua thuộc tính PerformanceObserver.supportedEntryTypes tĩnh.

Quan sát các mục đã xảy ra

Theo mặc định, các đối tượng PerformanceObserver chỉ có thể quan sát các mục nhập khi chúng xảy ra. Điều này có thể gây ra vấn đề nếu bạn muốn tải từng phần mã phân tích hiệu suất để mã không chặn các tài nguyên có mức độ ưu tiên cao hơn.

Để nhận các mục nhập trước đây (sau khi chúng xuất hiện), hãy đặt cờ buffered thành true khi bạn gọi observe(). Trình duyệt sẽ đưa các mục nhập trước đây vào vùng đệm mục nhập hiệu suất vào lần đầu tiên lệnh gọi lại PerformanceObserver được gọi.

po.observe({
  type: 'some-entry-type',
  buffered: true,
});

Những API hiệu suất cũ cần tránh

Trước khi có Performance Observer API, nhà phát triển có thể truy cập vào các mục hiệu suất bằng cách dùng 3 phương thức sau được xác định trên đối tượng performance:

Mặc dù các API này vẫn được hỗ trợ, nhưng bạn không nên sử dụng chúng vì chúng không cho phép bạn nghe khi các mục nhập mới được phát ra. Ngoài ra, nhiều API mới (chẳng hạn như Long Tasks) không được hiển thị thông qua đối tượng performance mà chỉ hiển thị thông qua PerformanceObserver.

Trừ phi bạn cần khả năng tương thích cụ thể với Internet Explorer, tốt nhất là nên tránh sử dụng các phương thức này trong mã và sử dụng PerformanceObserver từ giờ trở đi.

API Thời gian người dùng

API Thời gian người dùng là một API đo lường đa năng cho các chỉ số dựa trên thời gian. Thuộc tính này cho phép bạn tuỳ ý đánh dấu các điểm theo thời gian rồi đo lường khoảng thời gian giữa các điểm đó vào lúc khác.

// Record the time immediately before running a task.
performance.mark('myTask:start');
await doMyTask();

// Record the time immediately after running a task.
performance.mark('myTask:end');

// Measure the delta between the start and end of the task
performance.measure('myTask', 'myTask:start', 'myTask:end');

Mặc dù các API như Date.now() hoặc performance.now() cũng cung cấp cho bạn những khả năng tương tự, nhưng lợi ích của việc sử dụng API Thời gian người dùng là tích hợp tốt với công cụ hiệu suất. Ví dụ: Công cụ của Chrome cho nhà phát triển trực quan hoá các chỉ số đo lường Thời gian người dùng trong bảng Hiệu suất và nhiều nhà cung cấp dịch vụ phân tích cũng sẽ tự động theo dõi mọi hoạt động đo lường mà bạn thực hiện và gửi dữ liệu thời lượng đến phần phụ trợ phân tích của họ.

Để báo cáo hoạt động đo lường Thời gian người dùng, bạn có thể sử dụng PerformanceObserver và đăng ký để quan sát các mục thuộc loại measure:

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create the performance observer.
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // Log the entry and all associated details.
      console.log(entry.toJSON());
    }
  });

  // Start listening for `measure` entries to be dispatched.
  po.observe({type: 'measure', buffered: true});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

API Tác vụ dài

Hỗ trợ trình duyệt

  • 58
  • 79
  • x
  • x

Nguồn

Long Tasks API giúp bạn biết thời điểm luồng chính của trình duyệt bị chặn đủ lâu để ảnh hưởng đến tốc độ khung hình hoặc độ trễ đầu vào. API sẽ báo cáo mọi tác vụ thực thi lâu hơn 50 mili giây.

Bất cứ khi nào cần chạy mã đắt tiền hoặc tải và thực thi các tập lệnh lớn, bạn nên theo dõi xem mã đó có chặn luồng chính hay không. Trên thực tế, nhiều chỉ số ở cấp cao hơn được xây dựng dựa trên chính API Long Tasks (chẳng hạn như Thời gian tương tác (TTI)Tổng thời gian chặn (TBT)).

Để xác định thời điểm diễn ra các tác vụ cần thời gian dài, bạn có thể sử dụng PerformanceObserver và đăng ký để quan sát các mục thuộc loại longtask:

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create the performance observer.
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // Log the entry and all associated details.
      console.log(entry.toJSON());
    }
  });

  // Start listening for `longtask` entries to be dispatched.
  po.observe({type: 'longtask', buffered: true});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

API Thời gian phần tử

Hỗ trợ trình duyệt

  • 77
  • 79
  • x
  • x

Nguồn

Chỉ số Nội dung lớn nhất hiển thị (LCP) rất hữu ích khi biết thời điểm hình ảnh hoặc khối văn bản lớn nhất được hiển thị lên màn hình, nhưng trong một số trường hợp, bạn muốn đo thời gian hiển thị của một phần tử khác.

Đối với những trường hợp này, hãy sử dụng Element Timing API. LCP API thực sự được xây dựng dựa trên API Thời gian phần tử và thêm tính năng báo cáo tự động cho phần tử có nội dung lớn nhất. Tuy nhiên, bạn cũng có thể báo cáo về các phần tử khác bằng cách thêm rõ ràng thuộc tính elementtiming vào các phần tử đó và đăng ký PerformanceObserver để quan sát loại mục nhập element.

<img elementtiming="hero-image" />
<p elementtiming="important-paragraph">This is text I care about.</p>
<!-- ... -->

<script>
  // Catch errors since some browsers throw when using the new `type` option.
  // https://bugs.webkit.org/show_bug.cgi?id=209216
  try {
    // Create the performance observer.
    const po = new PerformanceObserver((entryList) => {
      for (const entry of entryList.getEntries()) {
        // Log the entry and all associated details.
        console.log(entry.toJSON());
      }
    });

    // Start listening for `element` entries to be dispatched.
    po.observe({type: 'element', buffered: true});
  } catch (e) {
    // Do nothing if the browser doesn't support this API.
  }
</script>

API Thời gian sự kiện

Chỉ số Tương tác với lần hiển thị tiếp theo (INP) đánh giá khả năng phản hồi tổng thể của trang bằng cách quan sát tất cả các lần nhấp, nhấn và bàn phím trong suốt thời gian hoạt động của một trang. INP của một trang thường là tương tác mất nhiều thời gian nhất để hoàn tất nhất, từ thời điểm người dùng bắt đầu tương tác đến thời điểm trình duyệt hiển thị khung tiếp theo cho thấy kết quả trực quan từ hoạt động đầu vào của người dùng.

Chỉ số INP có thể được thực hiện nhờ Event Timing API. API này hiển thị một số dấu thời gian xảy ra trong vòng đời sự kiện, bao gồm:

  • startTime: thời điểm trình duyệt nhận được sự kiện.
  • processingStart: thời gian mà trình duyệt có thể bắt đầu xử lý trình xử lý sự kiện cho sự kiện.
  • processingEnd: thời gian khi trình duyệt hoàn tất việc thực thi tất cả mã đồng bộ được bắt đầu từ các trình xử lý sự kiện cho sự kiện này.
  • duration: khoảng thời gian (được làm tròn thành 8 mili giây vì lý do bảo mật) tính từ khi trình duyệt nhận được sự kiện cho đến khi có thể vẽ khung tiếp theo sau khi hoàn tất việc thực thi tất cả mã đồng bộ được bắt đầu từ trình xử lý sự kiện.

Ví dụ sau đây cho thấy cách sử dụng các giá trị này để tạo các phép đo tuỳ chỉnh:

// Catch errors some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  const po = new PerformanceObserver((entryList) => {
    // Get the last interaction observed:
    const entries = Array.from(entryList.getEntries()).forEach((entry) => {
      // Get various bits of interaction data:
      const inputDelay = entry.processingStart - entry.startTime;
      const processingTime = entry.processingEnd - entry.processingStart;
      const duration = entry.duration;
      const eventType = entry.name;
      const target = entry.target || "(not set)"

      console.log("----- INTERACTION -----");
      console.log(`Input delay (ms): ${inputDelay}`);
      console.log(`Event handler time (ms): ${processingTime}`);
      console.log(`Total event duration (ms): ${duration}`);
      console.log(`Event type: ${eventType}`);
      console.log(target);
    });
  });

  // A durationThreshold of 16ms is necessary to surface more
  // interactions, since the default is 104ms. The minimum
  // durationThreshold is 16ms.
  po.observe({type: 'event', buffered: true, durationThreshold: 16});
} catch (error) {
  // Do nothing if the browser doesn't support this API.
}

API Thời gian tài nguyên

API Thời gian tài nguyên cung cấp cho nhà phát triển thông tin chi tiết về cách tải tài nguyên cho một trang cụ thể. Mặc dù API này có tên như vậy, thông tin mà API này cung cấp không chỉ giới hạn ở dữ liệu thời gian (mặc dù còn có rất nhiều thông tin như vậy). Các dữ liệu khác mà bạn có thể truy cập bao gồm:

  • initiatorType: cách tìm nạp tài nguyên: chẳng hạn như từ thẻ <script> hay <link> hoặc từ lệnh gọi fetch().
  • nextHopProtocol: giao thức dùng để tìm nạp tài nguyên, chẳng hạn như h2 hoặc quic.
  • encodedBodySize/decodedBodySize]: kích thước của tài nguyên ở dạng được mã hoá hoặc giải mã (tương ứng)
  • transferSize: kích thước của tài nguyên thực sự được chuyển qua mạng. Khi bộ nhớ đệm thực hiện các tài nguyên, giá trị này có thể nhỏ hơn nhiều so với encodedBodySize và trong một số trường hợp, giá trị này có thể bằng 0 (nếu không yêu cầu xác thực lại bộ nhớ đệm).

Bạn có thể sử dụng thuộc tính transferSize của các mục nhập thời gian tài nguyên để đo lường chỉ số tỷ lệ truy cập vào bộ nhớ đệm hoặc chỉ số tổng dung lượng tài nguyên được lưu vào bộ nhớ đệm. Điều này có thể hữu ích trong việc giúp bạn hiểu được chiến lược lưu tài nguyên vào bộ nhớ đệm ảnh hưởng như thế nào đến hiệu suất của những khách truy cập quay lại nhiều lần.

Ví dụ sau đây ghi lại tất cả tài nguyên mà trang yêu cầu và cho biết liệu mỗi tài nguyên đã được bộ nhớ đệm thực hiện hay chưa.

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create the performance observer.
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // If transferSize is 0, the resource was fulfilled via the cache.
      console.log(entry.name, entry.transferSize === 0);
    }
  });

  // Start listening for `resource` entries to be dispatched.
  po.observe({type: 'resource', buffered: true});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

Hỗ trợ trình duyệt

  • 57
  • 12
  • 58
  • 15

Nguồn

Navigation Timing API tương tự như Resource Timing API, nhưng chỉ báo cáo các yêu cầu điều hướng. Loại mục nhập navigation cũng tương tự như loại mục nhập resource nhưng chứa một số thông tin bổ sung dành riêng cho các yêu cầu điều hướng (chẳng hạn như khi các sự kiện DOMContentLoadedload kích hoạt).

Một chỉ số mà nhiều nhà phát triển theo dõi để nắm được thời gian phản hồi của máy chủ (Time to First Byte (TTFB)) có sẵn bằng cách sử dụng Navigation Timing API – cụ thể là dấu thời gian responseStart của mục nhập.

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create the performance observer.
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // If transferSize is 0, the resource was fulfilled via the cache.
      console.log('Time to first byte', entry.responseStart);
    }
  });

  // Start listening for `navigation` entries to be dispatched.
  po.observe({type: 'navigation', buffered: true});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

Một chỉ số khác mà các nhà phát triển sử dụng trình chạy dịch vụ có thể quan tâm là thời gian khởi động trình chạy dịch vụ cho các yêu cầu điều hướng. Đây là khoảng thời gian mà trình duyệt cần để bắt đầu luồng trình chạy dịch vụ trước khi có thể bắt đầu chặn các sự kiện tìm nạp.

Thời gian khởi động trình chạy dịch vụ cho một yêu cầu điều hướng cụ thể có thể được xác định từ delta giữa entry.responseStartentry.workerStart.

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create the performance observer.
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      console.log('Service Worker startup time:',
          entry.responseStart - entry.workerStart);
    }
  });

  // Start listening for `navigation` entries to be dispatched.
  po.observe({type: 'navigation', buffered: true});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

API Thời gian máy chủ

Server Timing API cho phép bạn truyền dữ liệu thời gian dành riêng cho yêu cầu từ máy chủ đến trình duyệt thông qua các tiêu đề phản hồi. Ví dụ: bạn có thể cho biết khoảng thời gian cần để tra cứu dữ liệu trong cơ sở dữ liệu cho một yêu cầu cụ thể. Việc này có thể hữu ích trong việc gỡ lỗi các vấn đề về hiệu suất do máy chủ hoạt động chậm.

Đối với những nhà phát triển sử dụng nhà cung cấp dịch vụ phân tích bên thứ ba, Server Timing API là cách duy nhất để tạo mối liên hệ giữa dữ liệu hiệu suất của máy chủ với các chỉ số kinh doanh khác mà những công cụ phân tích này có thể đang đo lường.

Để chỉ định dữ liệu về thời gian của máy chủ trong phản hồi, bạn có thể sử dụng tiêu đề phản hồi Server-Timing. Dưới đây là một ví dụ.

HTTP/1.1 200 OK

Server-Timing: miss, db;dur=53, app;dur=47.2

Sau đó, từ các trang của mình, bạn có thể đọc dữ liệu này trên cả hai mục nhập resource hoặc navigation từ các API Thời gian tài nguyên và Thời gian điều hướng.

// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create the performance observer.
  const po = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // Logs all server timing data for this response
      console.log('Server Timing', entry.serverTiming);
    }
  });

  // Start listening for `navigation` entries to be dispatched.
  po.observe({type: 'navigation', buffered: true});
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}