Chỉ số tuỳ chỉnh

Việc có các chỉ số tập trung vào người dùng sẽ mang lại nhiều giá trị mà bạn có thể đo lường trên mọi trang web. Những chỉ số này giúp bạn:

  • Tìm hiểu cách người dùng thực trải nghiệm web tổng thể.
  • 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ở tốt, nhưng trong nhiều trường hợp, bạn cần đo lường nhiều hơn những chỉ số này để nắm bắt 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 của trải nghiệm trên trang web mà có thể chỉ á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.
  • Thời gian để một trang hiển thị dữ liệu được tìm nạp từ cơ sở dữ liệu cho người dùng đã đăng nhập.
  • Thời gian cần thiết để ứng dụng kết xuất phía máy chủ (SSR) tái tạo.
  • Tỷ lệ truy cập bộ nhớ đệm cho các tài nguyên do khách truy cập cũ tải.
  • Độ trễ sự kiện của các sự kiện nhấp hoặc sự kiện bàn phím trong trò chơi.

API để đo lường chỉ số tuỳ chỉnh

Trước đây, các nhà phát triển web không có nhiều API cấp thấp để đo lường hiệu suất. Do đó, họ đã phải sử dụng các thủ thuật để đ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 đó là một tác vụ dài. Tuy nhiên, bạn không nên sử dụng các bản hack như vậy vì chúng thực sự ảnh hưởng đến hiệu suất (ví dụ: làm tiêu hao pin).

Quy tắc đầu tiên để đo lường hiệu suất hiệu quả là đảm bảo rằng các kỹ thuật đo lường hiệu suất của bạn không tự gây ra 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, tốt nhất bạn nên sử dụng một trong các API sau nếu có thể.

API Trình quan sát hiệu suất

Hỗ trợ trình duyệt

  • Chrome: 52.
  • Edge: 79.
  • Firefox: 57.
  • Safari: 11.

Nguồn

API Trình quan sát hiệu suất 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à bạn phải có được dữ liệu chất lượng cao.

Bạn có thể sử dụng PerformanceObserver để đăng ký thụ động các sự kiện liên quan đến hiệu suất. Đ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 hiệu suất mới được gửi đi. Sau đó, bạn sẽ cho trình quan sát biết những loại mục cần theo dõi bằng cách sử dụng phương thức observe():

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'});

Các phần sau đây liệt kê tất cả các loại mục nhập có thể quan sát được, nhưng trong các trình duyệt mới hơn, bạn có thể kiểm tra xem có những loại mục nhập nào 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 khi chúng xảy ra. Điều này có thể gây ra sự cố nếu bạn muốn tải mã phân tích hiệu suất theo phương thức tải lười để 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 trong quá khứ (sau khi các mục nhập đó xảy ra), hãy đặt cờ buffered thành true khi bạn gọi observe(). Trình duyệt sẽ bao gồm các mục nhập trước đây từ vùng đệm mục nhập hiệu suất trong lần đầu tiên lệnh gọi lại PerformanceObserver được gọi, lên đến kích thước vùng đệm tối đa cho loại đó.

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

Các 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 sử 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 các API này vì chúng không cho phép bạn nghe thời điểm phát hành mục mới. Ngoài ra, nhiều API mới (chẳng hạn như largest-contentful-paint) không được hiển thị thông qua đối tượng performance, mà chỉ được hiển thị thông qua PerformanceObserver.

Trừ phi bạn cần đặc biệt tương thích với Internet Explorer, tốt nhất bạn nên tránh sử dụng các phương thức này trong mã và sử dụng PerformanceObserver trong tương lai.

User Timing API

Hỗ trợ trình duyệt

  • Chrome: 28.
  • Edge: 12.
  • Firefox: 38.
  • Safari: 11.

Nguồn

User Timing API là một API đo lường cho nhiều mục đích dành cho các chỉ số dựa trên thời gian. Hàm này cho phép bạn đánh dấu tuỳ ý các điểm trong thời gian, sau đó đo lường khoảng thời gian giữa các điểm đánh dấu đó.

// 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() cung cấp cho bạn các khả năng tương tự, nhưng lợi ích của việc sử dụng API User Timing là API này tích hợp tốt với công cụ hiệu suất. Ví dụ: Công cụ phát triển Chrome trực quan hoá các phép đo Thời gian của người dùng trong bảng điều khiển Hiệu suất. Ngoài ra, nhiều nhà cung cấp dịch vụ phân tích cũng sẽ tự động theo dõi mọi phép đo 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 các phép đo Thời gian của người dùng, bạn có thể sử dụng PerformanceObserver và đăng ký để quan sát các mục nhập thuộc loại measure:

// 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});

Long Tasks API

Hỗ trợ trình duyệt

  • Chrome: 58.
  • Edge: 79.
  • Firefox: không được hỗ trợ.
  • Safari: không được hỗ trợ.

Nguồn

Long Tasks API (API tác vụ dài) hữu ích trong việc 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 bạn cần chạy mã tốn kém hoặc tải và thực thi 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 Tác vụ dài (chẳng hạn như Thời gian phản hồi (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:

// 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});

API Khung ảnh động dài

Hỗ trợ trình duyệt

  • Chrome: 123.
  • Cạnh: 123.
  • Firefox: không được hỗ trợ.
  • Safari: không được hỗ trợ.

Nguồn

API Khung ảnh động dài là một phiên bản lặp lại mới của API Tác vụ dài, xem xét khung hình dài (thay vì tác vụ dài) trên 50 mili giây. Việc này giúp giải quyết một số điểm hạn chế của Long Tasks API, chẳng hạn như khả năng phân bổ hiệu quả hơn và phạm vi độ trễ có thể có vấn đề ở phạm vi rộng hơn.

Để xác định thời điểm xảy ra khung hình dài, bạn có thể sử dụng PerformanceObserver và đăng ký để quan sát các mục nhập thuộc loại long-animation-frame:

// 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 `long-animation-frame` entries to be dispatched.
po.observe({type: 'long-animation-frame', buffered: true});

API Element Timing

Hỗ trợ trình duyệt

  • Chrome: 77.
  • Edge: 79.
  • Firefox: không được hỗ trợ.
  • Safari: không được hỗ trợ.

Nguồn

Chỉ số Thời gian hiển thị nội dung lớn nhất (LCP) rất hữu ích để biết thời điểm hình ảnh hoặc khối văn bản lớn nhất được vẽ lên màn hình, nhưng trong một số trường hợp, bạn muốn đo lường thời gian kết xuất 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 (API Thời gian của phần tử). API LCP thực sự được xây dựng dựa trên API Element Timing và thêm tính năng báo cáo tự động về phần tử có nội dung lớn nhất, nhưng bạn cũng có thể báo cáo về các phần tử khác bằng cách thêm thuộc tính elementtiming vào các phần tử đó một cách rõ ràng 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>
  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});
</script>

API Thời gian sự kiện

Hỗ trợ trình duyệt

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 89.
  • Safari: không được hỗ trợ.

Nguồn

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

Chỉ số INP được cung cấp 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 của sự kiện, bao gồm:

  • startTime: thời điểm trình duyệt nhận được sự kiện.
  • processingStart: thời điể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 điểm trình duyệt 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 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:

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 presentationDelay = entry.startTime + entry.duration - entry.processingEnd;
    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 processing time (ms): ${processingTime}`);
    console.log(`Presentation delay (ms): ${presentationDelay}`);
    console.log(`Total event duration (ms): ${duration}`);
    console.log(`Event type: ${eventType}`);
    console.log(target);
  });
});

// A durationThreshold of 16ms is necessary to include more
// interactions, since the default is 104ms. The minimum
// durationThreshold is 16ms.
po.observe({type: 'event', buffered: true, durationThreshold: 16});

API Thời gian tài nguyên

Hỗ trợ trình duyệt

  • Chrome: 29.
  • Edge: 12.
  • Firefox: 35.
  • Safari: 11.

Nguồn

Resource Timing API (API Thời gian tải 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ù tên của API là như vậy, nhưng thông tin mà API cung cấp không chỉ giới hạn ở dữ liệu thời gian (mặc dù có rất nhiều dữ liệu thời gian). Dữ liệu khác mà bạn có thể truy cập bao gồm:

  • initiatorType: cách tài nguyên được tìm nạp: chẳng hạn như từ thẻ <script> hoặc <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 đã 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 truyề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 có thể bằng 0 (nếu không cần 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 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. Những chỉ số này có thể hữu ích trong việc tìm hiểu cách chiến lược lưu tài nguyên vào bộ nhớ đệm ảnh hưởng đến hiệu suất của khách truy cập thường xuyên.

Ví dụ sau đây ghi lại tất cả tài nguyên được 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.

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // If transferSize is 0, the resource was fulfilled using the cache.
    console.log(entry.name, entry.transferSize === 0);
  }
});

// Start listening for `resource` entries to be dispatched.
po.observe({type: 'resource', buffered: true});

Hỗ trợ trình duyệt

  • Chrome: 57.
  • Edge: 12.
  • Firefox: 58.
  • Safari: 15.

Nguồn

Navigation Timing API (API Thời gian điều hướng) tương tự như Resource Timing API (API Thời gian tài nguyên), 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 chỉ dành riêng cho các yêu cầu điều hướng (chẳng hạn như khi sự kiện DOMContentLoadedload kích hoạt).

Một chỉ số mà nhiều nhà phát triển theo dõi để hiểu 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.

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // If transferSize is 0, the resource was fulfilled using the cache.
    console.log('Time to first byte', entry.responseStart);
  }
});

// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});

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 trình duyệt cần để bắt đầu luồng worker dịch vụ trước khi có thể bắt đầu chặn các sự kiện tìm nạp.

Bạn có thể xác định 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ể từ delta giữa entry.responseStartentry.workerStart.

// 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});

API Thời gian của máy chủ

Hỗ trợ trình duyệt

  • Chrome: 65.
  • Edge: 79.
  • Firefox: 61.
  • Safari: 16.4.

Nguồn

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 thời gian cần thiết để tra cứu dữ liệu trong cơ sở dữ liệu cho một yêu cầu cụ thể. Điều 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ủ bị 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 thời gian 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 đó, trên các trang của mình, bạn có thể đọc dữ liệu này trên cả mục nhập resource hoặc navigation từ API Thời gian điều hướng và API Thời gian tài nguyên.

// 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});