Hiệu suất gỡ lỗi trong trường

Tìm hiểu cách phân bổ dữ liệu hiệu suất bằng thông tin gỡ lỗi để giúp bạn xác định và khắc phục các vấn đề của người dùng thực thông qua số liệu phân tích

Google cung cấp 2 danh mục công cụ để đo lường và gỡ lỗi hiệu suất:

  • Các công cụ trong Lab: Các công cụ như Lighthouse, trong đó trang của bạn được tải trong một môi trường mô phỏng có thể bắt chước nhiều điều kiện (ví dụ: mạng chậm và thiết bị di động cấp thấp).
  • Công cụ thực địa: Các công cụ như Báo cáo trải nghiệm người dùng trên Chrome (CrUX), một báo cáo dựa trên dữ liệu tổng hợp của người dùng thực trên Chrome. (Xin lưu ý rằng dữ liệu trường do các công cụ như PageSpeed InsightsSearch Console báo cáo được lấy từ dữ liệuCrUX.)

Mặc dù các công cụ tại hiện trường cung cấp dữ liệu chính xác hơn (dữ liệu thực sự đại diện cho trải nghiệm thực tế của người dùng), nhưng các công cụ trong phòng thí nghiệm thường tốt hơn trong việc giúp bạn xác định và khắc phục vấn đề.

Dữ liệu CrUX thể hiện chính xác hơn hiệu suất thực tế của trang, nhưng nếu biết điểm CrUX, bạn sẽ không thể tìm ra cách cải thiện hiệu suất.

Mặt khác, Lighthouse sẽ xác định các vấn đề và đưa ra các đề xuất cụ thể về cách cải thiện. Tuy nhiên, Lighthouse sẽ chỉ đưa ra đề xuất cho các vấn đề về hiệu suất phát hiện được tại thời điểm tải trang. Công cụ này không phát hiện các vấn đề chỉ xuất hiện do hoạt động tương tác của người dùng, chẳng hạn như cuộn hoặc nhấp vào các nút trên trang.

Việc này đặt ra một câu hỏi quan trọng: làm cách nào để thu thập thông tin gỡ lỗi cho Các chỉ số quan trọng về trang web hoặc các chỉ số khác về hiệu suất của người dùng thực trong trường hợp này?

Bài đăng này sẽ giải thích chi tiết những API bạn có thể sử dụng để thu thập thêm thông tin gỡ lỗi cho từng chỉ số Core Web Vitals hiện tại, đồng thời gợi ý cho bạn cách thu thập dữ liệu này trong công cụ phân tích hiện có.

Các API để phân bổ và gỡ lỗi

Điểm số tổng hợp về mức thay đổi bố cục (CLS)

Trong tất cả các chỉ số Core Web Vitals, có lẽ CLS là chỉ số mà việc thu thập thông tin gỡ lỗi trong trường này là quan trọng nhất. CLS được đo lường trong toàn bộ thời gian hoạt động của trang. Vì vậy, cách người dùng tương tác với trang (cách họ cuộn, nội dung họ nhấp vào, v.v.) có thể tác động đáng kể đến việc liệu bố cục có thay đổi hay không và thành phần nào đang thay đổi.

Hãy xem xét báo cáo sau đây của PageSpeed Insights:

Báo cáo Thông tin chi tiết về tốc độ trang có các giá trị CLS (Mức thay đổi bố cục tích luỹ) khác nhau
PageSpeed Insights hiển thị cả dữ liệu trường và dữ liệu phòng thí nghiệm nếu có, và dữ liệu này có thể khác nhau

Giá trị được báo cáo cho CLS trong phòng thí nghiệm (Lighthouse) so với CLS trong trường (dữ liệu CrUX) khá khác nhau. Điều này rất hợp lý nếu bạn cho rằng trang có thể có nhiều nội dung tương tác không được dùng khi kiểm thử trong Lighthouse.

Nhưng ngay cả khi hiểu rằng hoạt động tương tác của người dùng ảnh hưởng đến dữ liệu trường, bạn vẫn cần biết những phần tử nào trên trang đang chuyển đổi để dẫn đến điểm số là 0,28 ở phân vị thứ 75. Giao diện LayoutShiftAttribution giúp bạn làm điều đó.

Xem thông tin phân bổ thay đổi bố cục

Giao diện LayoutShiftAttribution hiển thị trên mỗi mục layout-shiftLayout Instability API phát ra.

Để biết nội dung giải thích chi tiết về cả hai giao diện này, hãy xem bài viết Gỡ lỗi thay đổi bố cục. Để phục vụ mục đích của bài đăng này, điều quan trọng bạn cần biết là với tư cách là nhà phát triển, bạn có thể quan sát mọi thay đổi về bố cục xảy ra trên trang cũng như những phần tử nào đang thay đổi.

Dưới đây là một số mã mẫu sẽ ghi lại từng lần thay đổi bố cục cũng như các phần tử đã thay đổi:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

Việc đo lường và gửi dữ liệu đến công cụ phân tích cho mọi lần thay đổi bố cục xảy ra là không thiết thực. Tuy nhiên, bằng cách theo dõi tất cả các lần thay đổi, bạn có thể theo dõi những lần chuyển đổi tồi tệ nhất và chỉ báo cáo thông tin về những thay đổi đó.

Mục tiêu không phải là xác định và khắc phục mọi thay đổi bố cục xảy ra đối với mọi người dùng; mục tiêu là xác định những thay đổi ảnh hưởng đến số lượng người dùng lớn nhất và do đó đóng góp nhiều nhất vào CLS (Mức thay đổi bố cục tích luỹ) của trang ở phân vị thứ 75.

Ngoài ra, bạn không cần tính toán phần tử nguồn lớn nhất mỗi khi có sự thay đổi, mà chỉ cần thực hiện khi đã sẵn sàng gửi giá trị CLS đến công cụ phân tích của mình.

Mã sau đây lấy danh sách các mục nhập layout-shift đã đóng góp vào CLS (Mức thay đổi bố cục tích luỹ) và trả về phần tử nguồn lớn nhất từ mức thay đổi lớn nhất:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

Sau khi xác định được yếu tố lớn nhất góp phần dẫn đến sự thay đổi lớn nhất, bạn có thể báo cáo yếu tố đó cho công cụ phân tích.

Phần tử đóng góp nhiều nhất vào CLS cho một trang nhất định có thể sẽ khác nhau tuỳ theo người dùng, nhưng nếu tổng hợp các phần tử đó trên tất cả người dùng, bạn có thể tạo danh sách các phần tử thay đổi ảnh hưởng đến nhiều người dùng nhất.

Sau khi bạn xác định và khắc phục nguyên nhân gốc khiến các phần tử thay đổi đó, mã phân tích của bạn sẽ bắt đầu báo cáo các thay đổi nhỏ hơn được coi là thay đổi "xấu nhất" cho các trang của bạn. Cuối cùng, tất cả các thay đổi được báo cáo sẽ đủ nhỏ để đảm bảo các trang của bạn hoạt động tốt trong ngưỡng "tốt" là 0,1!

Một số siêu dữ liệu khác có thể hữu ích khi thu thập cùng với phần tử nguồn dịch chuyển lớn nhất là:

  • Thời điểm có sự chuyển dịch lớn nhất
  • Đường dẫn URL tại thời điểm xảy ra sự thay đổi lớn nhất (đối với các trang web cập nhật URL một cách linh động, chẳng hạn như Ứng dụng trang đơn).

Thời gian hiển thị nội dung lớn nhất (LCP)

Để gỡ lỗi LCP trong trường này, thông tin chính bạn cần là phần tử cụ thể nào là phần tử lớn nhất (phần tử ứng viên LCP) cho một lượt tải trang cụ thể đó.

Xin lưu ý rằng điều hoàn toàn có thể xảy ra là trên thực tế, điều khá phổ biến là phần tử đề xuất LCP sẽ khác nhau giữa người dùng với người dùng, ngay cả đối với cùng một trang.

Điều này có thể xảy ra vì một vài lý do:

  • Thiết bị của người dùng có độ phân giải màn hình khác nhau, dẫn đến bố cục trang khác nhau và do đó các phần tử khác nhau hiển thị trong khung nhìn.
  • Không phải lúc nào người dùng cũng tải trang mà người dùng cuộn lên đầu trang. Thông thường, các đường liên kết sẽ chứa giá trị nhận dạng theo mảnh hoặc thậm chí là đoạn văn bản, nghĩa là có thể trang của bạn được tải và hiển thị ở bất kỳ vị trí cuộn nào trên trang.
  • Nội dung có thể được cá nhân hoá cho người dùng hiện tại, vì vậy, phần tử ứng viên LCP có thể thay đổi rất nhiều giữa các người dùng.

Điều này có nghĩa là bạn không thể đưa ra giả định về việc phần tử hoặc tập hợp phần tử nào sẽ là phần tử ứng viên LCP phổ biến nhất cho một trang cụ thể. Bạn phải đo lường điều này dựa trên hành vi thực tế của người dùng.

Xác định phần tử ứng viên LCP

Để xác định phần tử đề xuất LCP trong JavaScript, bạn có thể sử dụng lớn nhất của Contentful Paint API (API Nội dung lớn nhất hiển thị), cùng một API mà bạn sử dụng để xác định giá trị thời gian LCP.

Khi quan sát các mục nhập largest-contentful-paint, bạn có thể xác định phần tử ứng viên LCP hiện tại bằng cách xem thuộc tính element của mục gần nhất:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

Sau khi biết phần tử ứng viên LCP, bạn có thể gửi phần tử này đến công cụ phân tích cùng với giá trị chỉ số. Giống như CLS, điều này sẽ giúp bạn xác định yếu tố nào là quan trọng nhất để tối ưu hoá trước.

Ngoài phần tử ứng viên LCP, bạn cũng nên đo lường thời gian của các phần phụ LCP. Điều này có thể hữu ích trong việc xác định những bước tối ưu hoá cụ thể nào phù hợp với trang web của bạn.

Lượt tương tác đến nội dung hiển thị tiếp theo (INP)

Các bit thông tin quan trọng nhất cần thu thập tại trường INP là:

  1. Phần tử nào được tương tác
  2. Tại sao loại tương tác này
  3. Thời điểm hoạt động tương tác đó diễn ra

Nguyên nhân chính gây ra tình trạng tương tác chậm là luồng chính bị chặn. Tình trạng này thường xảy ra trong khi JavaScript đang tải. Việc biết được liệu hầu hết các lượt tương tác chậm có xảy ra trong khi tải trang hay không sẽ giúp ích trong việc xác định những việc cần làm để khắc phục vấn đề.

Chỉ số INP xem xét độ trễ đầy đủ của một lượt tương tác, bao gồm cả thời gian cần thiết để chạy mọi trình nghe sự kiện đã đăng ký cũng như thời gian cần để hiển thị khung hình tiếp theo sau khi tất cả trình nghe sự kiện đã chạy. Điều này có nghĩa là đối với INP, bạn cần biết phần tử mục tiêu nào có xu hướng dẫn đến tương tác chậm và đó là những loại tương tác nào.

Mã sau đây ghi lại yếu tố mục tiêu và thời gian của mục nhập INP.

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);
  console.log('INP time:', inpEntry.startTime);
}

Lưu ý rằng mã này không cho biết cách xác định mục nhập event nào là mục nhập INP, vì logic đó có liên quan hơn. Tuy nhiên, phần sau đây giải thích cách lấy thông tin này bằng cách sử dụng thư viện JavaScript web-vitals.

Sử dụng với thư viện JavaScript quan trọng

Các phần trước đưa ra một số đề xuất chung và ví dụ về mã để ghi lại thông tin gỡ lỗi và đưa vào dữ liệu mà bạn gửi đến công cụ phân tích.

Kể từ phiên bản 3, thư viện JavaScript web-vitals sẽ bao gồm một bản dựng phân bổ hiển thị tất cả thông tin này và một vài tín hiệu bổ sung.

Ví dụ về mã sau đây cho thấy cách bạn có thể đặt một tham số sự kiện bổ sung (hoặc phương diện tuỳ chỉnh) chứa chuỗi gỡ lỗi hữu ích trong việc giúp xác định nguyên nhân gốc của các vấn đề về hiệu suất.

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Mã này dành riêng cho Google Analytics, nhưng ý tưởng chung cũng nên chuyển sang các công cụ phân tích khác.

Mã này cũng chỉ cho biết cách báo cáo về một tín hiệu gỡ lỗi duy nhất, nhưng việc có thể thu thập và báo cáo nhiều tín hiệu cho mỗi chỉ số sẽ rất hữu ích.

Ví dụ: để gỡ lỗi INP, bạn có thể muốn thu thập phần tử đang tương tác, loại tương tác, thời gian, loadState, giai đoạn tương tác và nhiều dữ liệu khác (chẳng hạn như dữ liệu Khung ảnh động dài).

Bản dựng phân bổ web-vitals hiển thị thêm thông tin phân bổ, như trong ví dụ sau về INP:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      eventParams.debug_type = attribution.interactionType;
      eventParams.debug_time = attribution.interactionTime;
      eventParams.debug_load_state = attribution.loadState;
      eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams.debug_presentation_delay =  Math.round(attribution.presentationDelay);
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Hãy tham khảo tài liệu về phân bổ web-vitals để biết danh sách đầy đủ các tín hiệu gỡ lỗi được hiển thị.

Báo cáo và trực quan hoá dữ liệu

Sau khi bạn bắt đầu thu thập thông tin gỡ lỗi cùng với các giá trị chỉ số, bước tiếp theo là tổng hợp dữ liệu trên tất cả người dùng để bắt đầu tìm kiếm các mẫu và xu hướng.

Như đã đề cập trước đó, bạn không nhất thiết phải giải quyết mọi vấn đề mà người dùng đang gặp phải. Bạn nên giải quyết mọi vấn đề mà người dùng đang gặp phải (đặc biệt là ở giai đoạn đầu tiên) những vấn đề ảnh hưởng đến số lượng người dùng lớn nhất. Đây cũng sẽ là những vấn đề có tác động tiêu cực nhất đến điểm số Core Web Vitals.

Đối với GA4, hãy xem bài viết riêng về cách truy vấn và trực quan hoá dữ liệu bằng BigQuery.

Tóm tắt

Hy vọng bài đăng này đã trình bày các cách cụ thể để bạn có thể sử dụng các API hiệu suất hiện có và thư viện web-vitals để lấy thông tin gỡ lỗi nhằm giúp chẩn đoán hiệu suất dựa trên những lượt truy cập của người dùng thực trong trường. Mặc dù hướng dẫn này tập trung vào Các chỉ số quan trọng về trang web, nhưng các khái niệm này cũng áp dụng cho việc gỡ lỗi mọi chỉ số hiệu suất có thể đo lường trong JavaScript.

Nếu mới bắt đầu đo lường hiệu suất và đã là người dùng Google Analytics, thì bạn có thể bắt đầu sử dụng công cụ Báo cáo Các chỉ số quan trọng về trang web vì công cụ này đã hỗ trợ báo cáo thông tin gỡ lỗi cho các Chỉ số quan trọng chính của trang web.

Nếu bạn là nhà cung cấp phân tích và đang tìm cách cải thiện sản phẩm cũng như cung cấp thêm thông tin gỡ lỗi cho người dùng, hãy cân nhắc sử dụng một số kỹ thuật được mô tả ở đây nhưng đừng chỉ tham khảo những ý tưởng được trình bày ở đây. Bài đăng này dành cho tất cả các công cụ phân tích. Tuy nhiên, mỗi công cụ phân tích có thể (và nên) thu thập và báo cáo nhiều thông tin gỡ lỗi hơn nữa.

Cuối cùng, nếu bạn cảm thấy còn thiếu khả năng gỡ lỗi các chỉ số này do thiếu tính năng hoặc thông tin trong chính API, hãy gửi ý kiến phản hồi đến web-vitals-feedback@googlegroups.com.