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á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) dựa trên dữ liệu tổng hợp, dữ liệu người dùng thực tế từ Chrome. (Xin lưu ý rằng dữ liệu trường do các công cụ như PageSpeed Insights và Search Console báo cáo được lấy từ dữ liệuCrUX.)
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ụ trong phòng 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.
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 số tất cả các chỉ số của Chỉ số quan trọng chính của trang web, CLS có lẽ là chỉ số quan trọng nhất mà bạn cần thu thập thông tin gỡ lỗi trong thực 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 (ví dụ: khoảng cách 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 của PageSpeed Insights:
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 thực hiện việc đó.
Xem thông tin 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-shift
mà Layout 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ụ cho 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});
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 yếu tố lớn nhất đang 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 của mình.
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ỏ để đả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 để thu thập cùng với phần tử nguồn thay đổi lớn nhất là:
- Thời điểm dịch chuyển nhiều 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 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 đ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ử đề 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 đ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 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ử đề 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)
Các bit thông tin quan trọng nhất cần thu thập tại trường INP là:
- Phần tử nào được tương tác
- Loại tương tác
- Thời điểm hoạt động tương tác đó diễn ra
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 đượ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 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 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 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);
}
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 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ã để 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 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 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 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 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 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);
onINP(sendToGoogleAnalytics);
Hãy tham khảo tài liệu về thuộc tính 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 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 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 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.