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 tế bằng số liệu phân tích

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

  • Công cụ thử nghiệm: 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ể mô phỏng 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) dựa trên dữ liệu tổng hợp, người dùng thực tế từ Chrome. (Xin lưu ý rằng dữ liệu thực tế do các công cụ như PageSpeed InsightsSearch Console báo cáo được lấy từ dữ liệu CrUX.)

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

Dữ liệu CrUX phản ánh hiệu suất thực tế của trang hơn, nhưng việc biết điểm số CrUX có thể sẽ không giúp bạn 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 đề 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 mà công cụ này 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.

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

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

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 số tất cả các chỉ số Core Web Vitals, CLS có lẽ là chỉ số quan trọng nhất đối với việc thu thập thông tin gỡ lỗi trong thực tế. CLS được đo lường trong suốt vòng đời của trang, vì vậy, cách người dùng tương tác với trang (chẳng hạn như họ cuộn bao xa, họ nhấp vào nội dung nào, v.v.) có thể ảnh hưởng đáng kể đến việc liệu có sự thay đổi bố cục hay không và những phần tử nào đang thay đổi.

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

Báo cáo PageSpeed Insights có nhiều giá trị CLS
PageSpeed Insights hiển thị cả dữ liệu thực địa và dữ liệu thử nghiệm (nếu có) và các dữ liệu này có thể khác nhau

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

Tuy nhiên, 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 thay đổi để dẫn đến điểm số 0,28 ở phân vị thứ 75. Giao diện LayoutShiftAttribution giúp bạn thực hiện việc đó.

Nhận mô hình phân bổ thay đổi bố cục

Giao diện LayoutShiftAttribution được hiển thị trên mỗi mục nhập 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 phần Gỡ lỗi các thay đổi về bố cục. Đối với mục đích của bài đăng này, điều chính 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ử đang thay đổi.

Dưới đây là một số mã mẫu ghi lại từng 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});

Có thể không thực tế khi đo lường và gửi dữ liệu đến công cụ phân tích cho mọi thay đổi về bố cục xảy ra; tuy nhiên, bằng cách theo dõi tất cả các thay đổi, bạn có thể theo dõi những thay đổ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 về bố cục xảy ra 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, từ đó đóng góp nhiều nhất vào CLS 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, bạn chỉ cần làm như vậy khi đã sẵn sàng gửi giá trị CLS đến công cụ phân tích.

Mã sau đây lấy danh sách các mục layout-shift đã đóng góp vào CLS và trả về phần tử nguồn lớn nhất từ sự 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 thành phần đóng góp nhiều nhất vào sự thay đổi lớn nhất, bạn có thể báo cáo thành phần đó 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ể khác nhau giữa người dùng này với người dùng khác, nhưng nếu tổng hợp các phần tử đó trên tất cả người dùng, bạn sẽ 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 rễ của các thay đổi đối với các phần tử đó, mã phân tích của bạn sẽ bắt đầu báo cáo các thay đổi nhỏ hơn là các thay đổi "tồi tệ nhất" đối với 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ỏ để các trang của bạn nằm trong ngưỡng "tốt" là 0,1!

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

  • Thời gian của sự thay đổi lớn nhất
  • Đường dẫn URL tại thời điểm 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 một trang).

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

Để gỡ lỗi LCP trong trường hợp thực tế, 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ử đề xuất LCP) cho lượt tải trang cụ thể đó.

Xin lưu ý rằng hoàn toàn có thể (thực tế là khá phổ biến) phần tử đề xuất LCP sẽ khác nhau giữa người dùng này với người dùng khác, 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:

  • Các thiết bị của người dùng có độ phân giải màn hình khác nhau, dẫn đến các bố cục trang khác nhau và do đó các phần tử khác nhau sẽ hiển thị trong khung nhìn.
  • Người dùng không phải lúc nào cũng tải các trang được cuộn lên trên cùng. Thông thường, các đường liên kết sẽ chứa mã nhận dạng mảnh hoặc thậm chí là mảnh văn bản, nghĩa là các trang của bạn có thể đượ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ử đề xuất LCP có thể khác nhau rất nhiều giữa người dùng này với người dùng khác.

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

Xác định phần tử đề xuất LCP

Để xác định phần tử đề xuất LCP trong JavaScript, bạn có thể sử dụng Largest Contentful Paint API (API Vẽ nội dung lớn nhất), chính là 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ử đề xuất LCP hiện tại bằng cách xem thuộc tính element của mục nhập gần đây 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ử đề xuất LCP, bạn có thể gửi phần tử đó đến công cụ phân tích cùng với giá trị chỉ số. Giống như CLS, chỉ số này sẽ giúp bạn xác định những phần tử quan trọng nhất cần tối ưu hoá trước tiên.

Ngoài phần tử đề xuất LCP, bạn cũng nên đo lường thời gian của các phần phụ trong 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ể 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)

Những thông tin quan trọng nhất cần thu thập trong trường cho INP là:

  1. Phần tử nào đã được tương tác
  2. Loại tương tác
  3. Thời điểm diễn ra lượt tương tác đó

Một nguyên nhân chính gây ra các lượt tương tác chậm là luồng chính bị chặn. Điều này có thể xảy ra phổ biến trong khi JavaScript đang tải. Việc biết liệu hầu hết các lượt tương tác chậm có xảy ra trong quá trình tải trang hay không sẽ giúp bạn 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 bất kỳ trình nghe sự kiện nào đã đăng ký cũng như thời gian cần thiết để vẽ 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 những phần tử mục tiêu nào có xu hướng dẫn đến các lượt tương tác chậm và đó là những loại lượt tương tác nào.

Mã sau đây ghi lại phần 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);
}

Xin 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 đó phức tạp hơn. Tuy nhiên, phần sau đây giải thích cách lấy thông tin này bằng thư viện JavaScript web-vitals.

Cách sử dụng với thư viện JavaScript web-vitals

Các phần trước đưa ra một số đề xuất chung và ví dụ về mã để thu thập thông tin gỡ lỗi nhằm đư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 bao gồm một bản dựng phân bổ hiển thị tất cả thông tin này cũng như một số tín hiệu bổ sung.

Ví dụ về mã sau đây cho biết cách bạn có thể đặt thêm một thông số sự kiện (hoặc phương diện tuỳ chỉnh) chứa một chuỗi gỡ lỗi hữu ích để giúp xác định nguyên nhân gốc rễ 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);
onINP(sendToGoogleAnalytics);

Mã này dành riêng cho Google Analytics, nhưng ý tưởng chung cũng sẽ áp dụng cho 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 sẽ rất hữu ích nếu bạn có thể thu thập và báo cáo về nhiều tín hiệu khác nhau cho mỗi chỉ số.

Ví dụ: để gỡ lỗi INP, bạn có thể muốn thu thập phần tử đang được tương tác, loại tương tác, thời gian, loadState, các giai đoạn tương tác và nhiều thông tin 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);
onINP(sendToGoogleAnalytics);

Hãy tham khảo tài liệu về mô hình 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 gặp phải. Đặc biệt là lúc đầu, bạn nên giải quyết những vấn đề ảnh hưởng đến nhiều người dùng nhất. Đây cũng là những vấn đề có tác động tiêu cực lớn nhất đến điểm số về các chỉ số Lõi của web.

Đối với GA4, hãy xem bài viết chuyên sâu 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 đã giúp bạn nêu ra những cách cụ thể để sử dụng các API hiệu suất hiện có và thư viện web-vitals nhằm lấy thông tin gỡ lỗi để giúp chẩn đoán hiệu suất dựa trên lượt truy cập của người dùng thực tế trong thực tế. 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 được trong JavaScript.

Nếu bạn 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 bằng công cụ Báo cáo chỉ số quan trọng của 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ố Chỉ số quan trọng chính của trang web.

Nếu bạn là nhà cung cấp dịch vụ phân tích và muốn 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 một số kỹ thuật được mô tả ở đây nhưng đừng giới hạn bản thân chỉ ở những ý tưởng được trình bày ở đây. Bài đăng này được áp dụng chung cho tất cả các công cụ phân tích; tuy nhiên, các công cụ phân tích riêng lẻ 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 mình không thể gỡ lỗi các chỉ số này do thiếu tính năng hoặc thông tin trong chính các API, hãy gửi ý kiến phản hồi đến web-vitals-feedback@googlegroups.com.