Một trong những lợi ích đáng kể nhất của nhân viên dịch vụ (ít nhất là từ góc độ hiệu suất) là khả năng chủ động kiểm soát việc lưu tài sản vào bộ nhớ đệm. Ứng dụng web có thể lưu tất cả các tài nguyên cần thiết vào bộ nhớ đệm sẽ tải nhanh hơn đáng kể cho khách truy cập quay lại. Nhưng lợi ích thực sự của những lợi ích này đối với người dùng thực sự là gì? Làm cách nào để đo lường điều này?
Ứng dụng web Google I/O (gọi tắt là IOWA) là một ứng dụng web tiến bộ tận dụng hầu hết tính năng mới do trình chạy dịch vụ cung cấp để mang lại trải nghiệm phong phú giống như ứng dụng cho người dùng. Họ cũng sử dụng Google Analytics để thu thập những dữ liệu quan trọng về hiệu suất và quy luật sử dụng của đối tượng người dùng rộng lớn và đa dạng.
Nghiên cứu điển hình này tìm hiểu cách IOWA sử dụng Google Analytics để trả lời các câu hỏi chính về hiệu suất và báo cáo về tác động thực tế của nhân viên dịch vụ.
Bắt đầu với những câu hỏi
Bất cứ khi nào bạn triển khai Analytics trong một trang web hoặc ứng dụng, điều quan trọng là phải bắt đầu bằng cách xác định các câu hỏi bạn đang cố gắng trả lời từ dữ liệu bạn sẽ thu thập.
Mặc dù có một số câu hỏi và chúng tôi muốn giải đáp, nhưng để phục vụ nghiên cứu điển hình này, chúng ta sẽ tập trung vào 2 câu hỏi thú vị hơn.
1. Việc lưu vào bộ nhớ đệm của trình chạy dịch vụ có hiệu quả hơn so với cơ chế lưu vào bộ nhớ đệm của HTTP hiện có trong mọi trình duyệt không?
Chúng tôi dự kiến các trang sẽ tải nhanh hơn cho khách truy cập cũ so với khách truy cập mới vì trình duyệt có thể lưu các yêu cầu vào bộ nhớ đệm và phân phát chúng ngay lập tức trong các lượt truy cập lặp lại.
Service worker cung cấp các khả năng lưu vào bộ nhớ đệm thay thế để cho phép nhà phát triển kiểm soát chi tiết chính xác nội dung và cách thức lưu vào bộ nhớ đệm. Trong IOWA, chúng tôi đã tối ưu hóa việc triển khai trình chạy dịch vụ để mọi nội dung sẽ được lưu vào bộ nhớ đệm, để khách truy cập cũ có thể sử dụng ứng dụng hoàn toàn ngoại tuyến.
Nhưng nỗ lực này có tốt hơn những gì trình duyệt đã làm theo mặc định không? Và nếu có thì tốt hơn bao nhiêu? 1
2. Trình chạy dịch vụ ảnh hưởng như thế nào đến trải nghiệm tải trang web?
Nói cách khác, cảm thấy trang web đang tải nhanh đến mức nào, bất kể thời gian tải thực tế được đo bằng các chỉ số tải trang truyền thống là bao nhiêu?
Rõ ràng là việc trả lời các câu hỏi về cảm nhận của một trải nghiệm không phải là một công việc dễ dàng, và không có chỉ số nào thể hiện hoàn toàn quan điểm chủ quan như vậy. Dù vậy, vẫn có một vài chỉ số tốt hơn những chỉ số khác, vì vậy, việc chọn chỉ số phù hợp đóng vai trò quan trọng.
Chọn chỉ số phù hợp
Theo mặc định, Google Analytics theo dõi thời gian tải trang (qua Navigation Timing API) cho 1% khách truy cập của trang web và cung cấp dữ liệu đó thông qua các chỉ số như Thời gian trung bình và Thời gian tải trang.
Số lượt xem trung bình Thời gian tải trang là một chỉ số tốt để trả lời câu hỏi đầu tiên của chúng ta, nhưng đây không phải là chỉ số đặc biệt tốt để trả lời câu hỏi thứ hai. Có một điều, sự kiện load
không nhất thiết tương ứng với thời điểm người dùng có thể thực sự tương tác với ứng dụng. Hơn nữa, 2 ứng dụng có cùng thời gian tải có thể cảm thấy tải theo cách khác nhau rất nhiều. Ví dụ: một trang web có màn hình chờ hoặc chỉ báo tải có thể cho cảm giác như trang web này tải nhanh hơn nhiều so với trang web chỉ hiển thị trang trống trong vài giây.
Trong IOWA, chúng tôi đã hiển thị một ảnh động đếm ngược trên màn hình chờ (theo ý kiến của tôi) rất thành công để giúp người dùng giải trí trong khi phần còn lại của ứng dụng tải ở chế độ nền. Do đó, việc theo dõi khoảng thời gian để màn hình chờ xuất hiện sẽ phù hợp hơn nhiều như một cách để đo lường hiệu suất tải quan sát được. Chúng tôi đã chọn chỉ số thời gian để hiển thị đầu tiên để nhận được giá trị này.
Sau khi quyết định chọn những câu hỏi mà chúng tôi muốn trả lời và xác định được các chỉ số sẽ hữu ích để trả lời câu hỏi đó, thì đã đến lúc triển khai Google Analytics và bắt đầu đo lường.
Việc triển khai Analytics
Nếu bạn đã sử dụng Google Analytics trước đây, thì bạn có thể quen thuộc với đoạn mã theo dõi JavaScript được đề xuất. Thông báo sẽ có dạng như sau:
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
Dòng đầu tiên trong mã trên khởi chạy hàm ga()
chung (nếu chưa có) và dòng cuối cùng tải thư viện analytics.js
xuống theo cách không đồng bộ.
Phần ở giữa chứa hai dòng sau:
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
Hai lệnh này theo dõi các trang mà người dùng truy cập vào trang web của bạn, nhưng không nhiều. Nếu muốn theo dõi các lượt tương tác khác của người dùng, bạn phải tự thực hiện.
Đối với IOWA, chúng tôi muốn theo dõi hai điều nữa:
- Khoảng thời gian trôi qua tính từ khi trang bắt đầu tải lần đầu tiên cho đến khi pixel xuất hiện trên màn hình.
- Liệu trình chạy dịch vụ có đang kiểm soát trang hay không. Với thông tin này, chúng tôi có thể phân đoạn báo cáo của mình để so sánh kết quả với và không có trình chạy dịch vụ.
Đang chụp thời gian để vẽ đầu tiên
Một số trình duyệt ghi lại thời điểm chính xác mà pixel đầu tiên được vẽ lên màn hình và cho phép nhà phát triển biết thời gian đó. Giá trị đó, so với giá trị navigationStart
được hiển thị qua Navigation Timing API cung cấp cho chúng ta tính toán rất chính xác về khoảng thời gian đã trôi qua từ khi người dùng yêu cầu trang lần đầu đến khi họ nhìn thấy nội dung nào đó lần đầu tiên.
Như tôi đã đề cập, thời gian để hiển thị lần đầu là một chỉ số quan trọng cần đo lường vì đó là điểm đầu tiên người dùng trải nghiệm tốc độ tải của trang web của bạn. Đó là ấn tượng đầu tiên mà người dùng nhận được. Ấn tượng đầu tiên tốt có thể ảnh hưởng tích cực đến trải nghiệm còn lại của người dùng.2
Để nhận giá trị hiển thị đầu tiên trong các trình duyệt hiển thị giá trị đó, chúng ta đã tạo hàm hiệu dụng getTimeToFirstPaintIfSupported
:
function getTimeToFirstPaintIfSupported() {
// Ignores browsers that don't support the Performance Timing API.
if (window.performance && window.performance.timing) {
var navTiming = window.performance.timing;
var navStart = navTiming.navigationStart;
var fpTime;
// If chrome, get first paint time from `chrome.loadTimes`.
if (window.chrome && window.chrome.loadTimes) {
fpTime = window.chrome.loadTimes().firstPaintTime * 1000;
}
// If IE/Edge, use the prefixed `msFirstPaint` property.
// See http://msdn.microsoft.com/ff974719
else if (navTiming.msFirstPaint) {
fpTime = navTiming.msFirstPaint;
}
if (fpTime && navStart) {
return fpTime - navStart;
}
}
}
Như vậy, giờ đây chúng ta có thể viết một hàm khác có khả năng gửi một sự kiện không tương tác với thời gian để hiển thị đầu tiên dưới dạng giá trị:3
function sendTimeToFirstPaint() {
var timeToFirstPaint = getTimeToFirstPaintIfSupported();
if (timeToFirstPaint) {
ga('send', 'event', {
eventCategory: 'Performance',
eventAction: 'firstpaint',
// Rounds to the nearest millisecond since
// event values in Google Analytics must be integers.
eventValue: Math.round(timeToFirstPaint)
// Sends this as a non-interaction event,
// so it doesn't affect bounce rate.
nonInteraction: true
});
}
}
Sau khi viết cả hai hàm này, mã theo dõi của chúng ta sẽ trông giống như sau:
// Creates the tracker object.
ga('create', 'UA-XXXXX-Y', 'auto');
// Sends a pageview for the initial pageload.
ga('send', 'pageview');
// Sends an event with the time to first paint data.
sendTimeToFirstPaint();
Lưu ý rằng tuỳ thuộc vào thời điểm mã ở trên chạy, pixel có thể đã hoặc chưa được vẽ lên màn hình. Để đảm bảo chúng ta luôn chạy mã này sau khi lần vẽ đầu tiên xảy ra, chúng ta đã trì hoãn lệnh gọi đến sendTimeToFirstPaint()
cho đến sau sự kiện load
. Trên thực tế, chúng tôi đã quyết định hoãn gửi tất cả dữ liệu phân tích cho đến sau khi trang được tải để đảm bảo rằng những yêu cầu đó sẽ không cạnh tranh với việc tải các tài nguyên khác.
// Creates the tracker object.
ga('create', 'UA-XXXXX-Y', 'auto');
// Postpones sending any hits until after the page has fully loaded.
// This prevents analytics requests from delaying the loading of the page.
window.addEventListener('load', function() {
// Sends a pageview for the initial pageload.
ga('send', 'pageview');
// Sends an event with the time to first paint data.
sendTimeToFirstPaint();
});
Mã ở trên báo cáo firstpaint
lần cho Google Analytics, nhưng đó mới chỉ là một nửa câu chuyện. Chúng tôi vẫn cần theo dõi trạng thái của trình chạy dịch vụ; nếu không, chúng tôi sẽ không thể so sánh thời gian hiển thị đầu tiên của trang do nhân viên dịch vụ kiểm soát và trang không được kiểm soát.
Xác định trạng thái của trình chạy dịch vụ
Để xác định trạng thái hiện tại của trình chạy dịch vụ, chúng ta đã tạo một hàm hiệu dụng trả về một trong ba giá trị:
- kiểm soát: trình chạy dịch vụ đang kiểm soát trang. Trong trường hợp IOWA, điều đó cũng có nghĩa là tất cả nội dung đã được lưu vào bộ nhớ đệm và trang hoạt động ngoại tuyến.
- được hỗ trợ: trình duyệt hỗ trợ trình chạy dịch vụ nhưng trình chạy dịch vụ chưa kiểm soát trang. Đây là trạng thái mong đợi cho khách truy cập lần đầu.
- không được hỗ trợ: trình duyệt của người dùng không hỗ trợ trình chạy dịch vụ.
function getServiceWorkerStatus() {
if ('serviceWorker' in navigator) {
return navigator.serviceWorker.controller ? 'controlled' : 'supported';
} else {
return 'unsupported';
}
}
Hàm này nhận được trạng thái của trình chạy dịch vụ cho chúng ta; bước tiếp theo là liên kết trạng thái này với dữ liệu mà chúng tôi đã gửi đến Google Analytics.
Theo dõi dữ liệu tuỳ chỉnh bằng phương diện tuỳ chỉnh
Theo mặc định, Google Analytics cung cấp cho bạn nhiều cách để chia nhỏ tổng lưu lượng truy cập của bạn thành các nhóm dựa trên thuộc tính của người dùng, phiên hoạt động hoặc lượt tương tác. Những thuộc tính này được gọi là phương diện. Những phương diện phổ biến mà các nhà phát triển web quan tâm là những phương diện như Trình duyệt, Hệ điều hành hoặc Danh mục thiết bị.
Trạng thái của trình chạy dịch vụ không phải là phương diện mà Google Analytics cung cấp theo mặc định; tuy nhiên, Google Analytics cho phép bạn tạo phương diện tuỳ chỉnh của riêng mình và xác định chúng theo cách mà bạn muốn.
Đối với IOWA, chúng tôi đã tạo thứ nguyên tùy chỉnh có tên là Trạng thái trình chạy dịch vụ và đặt phạm vi của thứ nguyên thành lượt truy cập (tức là mỗi lần tương tác).4 Mỗi thứ nguyên tùy chỉnh mà bạn tạo trong Google Analytics được cung cấp một chỉ mục duy nhất trong thuộc tính đó và trong mã theo dõi của bạn, bạn có thể tham chiếu thứ nguyên đó theo chỉ mục của thứ nguyên đó. Ví dụ: nếu chỉ mục của phương diện vừa tạo là 1, chúng ta có thể cập nhật logic như sau để gửi sự kiện firstpaint
bao gồm trạng thái của trình chạy dịch vụ:
ga('send', 'event', {
eventCategory: 'Performance',
eventAction: 'firstpaint',
// Rounds to the nearest millisecond since
// event values in Google Analytics must be integers.
eventValue: Math.round(timeToFirstPaint)
// Sends this as a non-interaction event,
// so it doesn't affect bounce rate.
nonInteraction: true,
// Sets the current service worker status as the value of
// `dimension1` for this event.
dimension1: getServiceWorkerStatus()
});
Thao tác này hiệu quả, nhưng sẽ chỉ liên kết trạng thái của trình chạy dịch vụ với sự kiện cụ thể này. Vì Trạng thái trình chạy dịch vụ là điều có thể hữu ích cần biết cho bất kỳ tương tác nào, tốt nhất bạn nên đưa trạng thái này vào tất cả dữ liệu được gửi đến Google Analytics.
Để bao gồm thông tin này trong tất cả các lượt truy cập (ví dụ: tất cả lượt xem trang, sự kiện, v.v.), chúng tôi đặt giá trị thứ nguyên tùy chỉnh trên chính đối tượng công cụ theo dõi trước khi gửi bất kỳ dữ liệu nào đến Google Analytics.
ga('set', 'dimension1', getServiceWorkerStatus());
Sau khi đặt, giá trị này sẽ được gửi cùng với tất cả các lượt truy cập tiếp theo cho tải trang hiện tại. Nếu sau đó người dùng tải trang lại, thì một giá trị mới có thể được trả về từ hàm getServiceWorkerStatus()
và giá trị đó sẽ được đặt trên đối tượng trình theo dõi.
Một lưu ý nhanh về tính rõ ràng và dễ đọc của mã: vì những người khác xem mã này có thể không biết dimension1
đề cập đến điều gì, nên tốt nhất bạn nên tạo một biến ánh xạ các tên thứ nguyên có ý nghĩa với các giá trị mà analytics.js sẽ sử dụng.
// Creates a map between custom dimension names and their index.
// This is particularly useful if you define lots of custom dimensions.
var customDimensions = {
SERVICE_WORKER_STATUS: 'dimension1'
};
// Creates the tracker object.
ga('create', 'UA-XXXXX-Y', 'auto');
// Sets the service worker status on the tracker,
// so its value is included in all future hits.
ga('set', customDimensions.SERVICE_WORKER_STATUS, getServiceWorkerStatus());
// Postpones sending any hits until after the page has fully loaded.
// This prevents analytics requests from delaying the loading of the page.
window.addEventListener('load', function() {
// Sends a pageview for the initial pageload.
ga('send', 'pageview');
// Sends an event with the time to first paint data.
sendTimeToFirstPaint();
});
Như tôi đã đề cập, việc gửi thứ nguyên Trạng thái trình chạy dịch vụ với mỗi lượt truy cập cho phép chúng tôi sử dụng thứ nguyên đó khi báo cáo về bất kỳ chỉ số nào.
Như bạn có thể thấy gần 85% trong tổng số lượt xem trang cho IOWA là từ các trình duyệt hỗ trợ service worker.
Kết quả: trả lời các câu hỏi của chúng tôi
Khi bắt đầu thu thập dữ liệu để trả lời câu hỏi, chúng tôi có thể báo cáo dữ liệu đó để xem kết quả. (Lưu ý: tất cả dữ liệu Google Analytics hiển thị ở đây thể hiện lưu lượng truy cập web thực tế vào trang web IOWA từ ngày 16 đến ngày 22 tháng 5 năm 2016).
Câu hỏi đầu tiên của chúng tôi là: Trình chạy dịch vụ có lưu vào bộ nhớ đệm hiệu quả hơn so với cơ chế lưu vào bộ nhớ đệm HTTP hiện có trong tất cả các trình duyệt không?
Để trả lời câu hỏi đó, chúng tôi đã tạo một báo cáo tuỳ chỉnh xem xét chỉ số Trung bình Thời gian tải trang trên nhiều phương diện. Chỉ số này rất phù hợp để trả lời câu hỏi này vì sự kiện load
chỉ kích hoạt sau khi bạn tải tất cả các tài nguyên ban đầu xuống. Do đó, thời gian này phản ánh trực tiếp tổng thời gian tải cho tất cả các tài nguyên quan trọng của trang web.5
Các phương diện chúng tôi chọn là:
- Phương diện Trạng thái trình chạy dịch vụ tuỳ chỉnh của chúng tôi.
- Kiểu người dùng: cho biết đây là lần đầu tiên người dùng truy cập vào trang web hay quay lại. (Lưu ý: khách truy cập mới sẽ không có bất kỳ tài nguyên nào được lưu vào bộ nhớ đệm; khách truy cập cũ thì có thể.)
- Danh mục thiết bị, giúp chúng tôi so sánh kết quả trên thiết bị di động và máy tính.
Để kiểm soát khả năng các yếu tố liên quan đến trình chạy dịch vụ làm sai lệch kết quả thời gian tải, chúng tôi đã giới hạn truy vấn của mình để chỉ bao gồm các trình duyệt hỗ trợ trình chạy dịch vụ.
Như bạn có thể thấy, các lượt truy cập vào ứng dụng của chúng tôi khi được kiểm soát bởi một nhân viên dịch vụ tải nhanh hơn khá nhiều so với các lượt truy cập không được kiểm soát, ngay cả những lượt truy cập từ người dùng cũ có thể đã lưu hầu hết tài nguyên của trang vào bộ nhớ đệm. Một điều thú vị nữa là nhận thấy rằng trung bình, khách truy cập sử dụng thiết bị di động có nhân viên dịch vụ thấy thời gian tải nhanh hơn so với khách truy cập mới trên máy tính.
"...số lượt truy cập vào ứng dụng của chúng tôi khi được kiểm soát bởi một nhân viên dịch vụ đã tải nhanh hơn khá nhiều so với số lượt truy cập không được kiểm soát..."
Bạn có thể xem thêm thông tin chi tiết trong 2 bảng sau:
Tỷ lệ thời lượng video Thời gian tải trang (Máy tính) | |||
---|---|---|---|
Trạng thái trình chạy dịch vụ | Loại Người Dùng | Thời gian tải trang tr.bình (mili giây) | Kích thước mẫu |
Đã kiểm soát | Khách truy cập cũ | 2568 | 30860 |
Có thể làm | Khách truy cập cũ | 3612 | 1289 |
Có thể làm | Khách truy cập mới | 4664 | 21991 |
Tỷ lệ thời lượng video Thời gian tải trang (Thiết bị di động) | |||
---|---|---|---|
Trạng thái trình chạy dịch vụ | Loại Người Dùng | Thời gian tải trang tr.bình (mili giây) | Kích thước mẫu |
Đã kiểm soát | Khách truy cập cũ | 3760 | 8162 |
Có thể làm | Khách truy cập cũ | 4843 | 676 |
Có thể làm | Khách truy cập mới | 6158 | 5779 |
Bạn có thể thắc mắc làm thế nào một khách truy cập quay lại có trình duyệt hỗ trợ trình chạy dịch vụ lại có thể ở trạng thái không được kiểm soát. Sau đây là một số lý do có thể giải thích cho vấn đề này:
- Người dùng đã rời khỏi trang trong lần truy cập đầu tiên trước khi service worker có cơ hội hoàn tất việc khởi chạy.
- Người dùng đã gỡ cài đặt trình chạy dịch vụ thông qua công cụ cho nhà phát triển.
Cả hai trường hợp này đều tương đối hiếm gặp. Chúng ta có thể thấy điều đó trong dữ liệu bằng cách xem các giá trị Mẫu tải trang trong cột thứ tư. Lưu ý rằng những hàng ở giữa có mẫu nhỏ hơn nhiều so với hai hàng còn lại.
Câu hỏi thứ hai của chúng tôi là: Trình chạy dịch vụ ảnh hưởng như thế nào đến trải nghiệm tải trang web?
Để trả lời câu hỏi này, chúng tôi đã tạo một báo cáo tuỳ chỉnh khác cho chỉ số Vị trí Giá trị sự kiện và lọc kết quả để chỉ bao gồm các sự kiện firstpaint
. Chúng tôi đã sử dụng phương diện Danh mục thiết bị và phương diện Trạng thái trình chạy dịch vụ tuỳ chỉnh.
Trái với những gì tôi mong đợi, trình chạy dịch vụ trên thiết bị di động có tác động ít hơn nhiều đến thời gian để vẽ đầu tiên so với khi tải trang tổng thể.
"...trình chạy dịch vụ trên thiết bị di động có tác động ít hơn nhiều đến thời gian hiển thị đầu tiên so với tổng thể tải trang."
Để tìm hiểu lý do dẫn đến trường hợp này, chúng ta cần tìm hiểu kỹ hơn về dữ liệu này. Mức trung bình có thể phù hợp cho thông tin tổng quan chung và nét vẽ rộng, nhưng để thực sự hiểu được cách những con số này được phân tích trên một phạm vi người dùng, chúng ta cần xem xét tỷ lệ phân phối của firstpaint
.
Nhận dữ liệu phân phối của một chỉ số trong Google Analytics
Để phân phối số lần firstpaint
, chúng ta cần có quyền truy cập vào từng kết quả của từng sự kiện. Rất tiếc, Google Analytics không làm cho việc này dễ dàng.
Google Analytics cho phép chúng tôi chia nhỏ báo cáo theo bất kỳ phương diện nào mà chúng tôi muốn, nhưng không cho phép chia nhỏ báo cáo theo chỉ số. Điều đó không có nghĩa là chúng ta không thể thực hiện điều đó, chỉ là chúng ta phải tuỳ chỉnh phương thức triển khai thêm một chút để có được kết quả mong muốn.
Vì chỉ có thể phân tích kết quả báo cáo theo phương diện, nên chúng tôi phải đặt giá trị chỉ số (trong trường hợp này là firstpaint
lần) làm phương diện tuỳ chỉnh cho sự kiện. Để làm điều này, chúng tôi đã tạo một thứ nguyên tùy chỉnh khác có tên là Giá trị chỉ số và cập nhật logic theo dõi firstpaint
như sau:
var customDimensions = {
SERVICE_WORKER_STATUS: 'dimension1',
<strong>METRIC_VALUE: 'dimension2'</strong>
};
// ...
function sendTimeToFirstPaint() {
var timeToFirstPaint = getTimeToFirstPaintIfSupported();
if (timeToFirstPaint) {
var fields = {
eventCategory: 'Performance',
eventAction: 'firstpaint',
// Rounds to the nearest millisecond since
// event values in Google Analytics must be integers.
eventValue: Math.round(timeToFirstPaint)
// Sends this as a non-interaction event,
// so it doesn't affect bounce rate.
nonInteraction: true
}
<strong>// Sets the event value as a dimension to allow for breaking down the
// results by individual metric values at reporting time.
fields[customDimensions.METRIC_VALUE] = String(fields.eventValue);</strong>
ga('send', 'event', fields);
}
}
Giao diện web của Google Analytics hiện không cung cấp cách trực quan hoá việc phân phối các giá trị chỉ số tuỳ ý, nhưng với sự trợ giúp của API báo cáo chính của Google Analytics và thư viện Google Biểu đồ, chúng tôi có thể truy vấn các kết quả thô và sau đó tự xây dựng biểu đồ.
Ví dụ: cấu hình yêu cầu API sau đây được dùng để phân phối các giá trị firstpaint
trên máy tính bằng một trình chạy dịch vụ không kiểm soát.
{
dateRanges: [{startDate: '2016-05-16', endDate: '2016-05-22'}],
metrics: [{expression: 'ga:totalEvents'}],
dimensions: [{name: 'ga:dimension2'}],
dimensionFilterClauses: [
{
operator: 'AND',
filters: [
{
dimensionName: 'ga:eventAction',
operator: 'EXACT',
expressions: ['firstpaint']
},
{
dimensionName: 'ga:dimension1',
operator: 'EXACT',
expressions: ['supported']
},
{
dimensionName: 'ga:deviceCategory',
operator: 'EXACT',
expressions: ['desktop']
}
],
}
],
orderBys: [
{
fieldName: 'ga:dimension2',
orderType: 'DIMENSION_AS_INTEGER'
}
]
}
Yêu cầu API này trả về một mảng các giá trị như sau (Lưu ý: đây chỉ là 5 kết quả đầu tiên). Kết quả được sắp xếp theo thứ tự từ nhỏ nhất đến lớn nhất, do đó các hàng này đại diện cho thời gian nhanh nhất.
Kết quả phản hồi của API (5 hàng đầu tiên) | |
---|---|
ga:dimension2 | ga:totalEvents |
4 | 3 |
5 | 2 |
6 | 10 |
7 | 8 |
8 | 10 |
Dưới đây là ý nghĩa của những kết quả này bằng tiếng Anh thuần tuý:
- Có 3 sự kiện mà giá trị
firstpaint
là 4 mili giây - Có 2 sự kiện giá trị
firstpaint
là 5 mili giây - Có 10 sự kiện có giá trị
firstpaint
là 6 mili giây - Có 8 sự kiện với giá trị
firstpaint
là 7 mili giây - Có 10 sự kiện mà
firstpaint
value
là 8 mili giây - v.v.
Từ các kết quả này, chúng ta có thể ngoại suy giá trị firstpaint
cho mỗi sự kiện đơn lẻ và tạo biểu đồ phân phối. Chúng tôi làm việc này cho mỗi truy vấn mà chúng tôi đã thực hiện.
Dưới đây là ví dụ về quá trình phân phối trên máy tính với một trình chạy dịch vụ không kiểm soát (nhưng được hỗ trợ):
![Thời gian để phân phối vị trí hiển thị đầu tiên trên máy tính (được hỗ trợ)](https://web.developers.google.cn/static/case-studies/service-worker-perf/image/time-first-paint-distrib-adc6d60d00c31.png?authuser=5&hl=vi)
Thời gian firstpaint
trung bình cho phân phối trên là 912 mili giây.
Hình dạng của đường cong này khá điển hình của sự phân phối thời gian tải. Ngược lại với biểu đồ bên dưới, biểu đồ này hiển thị việc phân phối sự kiện hiển thị đầu tiên cho các lượt truy cập mà trong đó một worker dịch vụ đang kiểm soát trang.
![Thời gian để phân phối màu đầu tiên trên máy tính (có kiểm soát)](https://web.developers.google.cn/static/case-studies/service-worker-perf/image/time-first-paint-distrib-0b74756b849ee.png?authuser=5&hl=vi)
Lưu ý rằng khi một trình chạy dịch vụ đang kiểm soát trang, nhiều khách truy cập gặp phải lần hiển thị đầu tiên gần như ngay lập tức, với trung vị là 583 mili giây.
"...khi một nhân viên dịch vụ đang kiểm soát trang, nhiều khách truy cập gặp phải trải nghiệm hiển thị đầu tiên gần như ngay lập tức..."
Để hiểu rõ hơn về cách hai bản phân phối này so sánh với nhau, biểu đồ tiếp theo sẽ hiển thị chế độ xem hợp nhất của hai loại. Biểu đồ thể hiện lượt truy cập của nhân viên dịch vụ không được kiểm soát được phủ lên đầu biểu đồ hiển thị số lượt truy cập được kiểm soát và cả hai đều được phủ lên đầu biểu đồ hiển thị cả hai.
![Thời gian để phân phối vị trí hiển thị đầu tiên trên máy tính](https://web.developers.google.cn/static/case-studies/service-worker-perf/image/time-first-paint-distrib-5f69da3b18e2c.png?authuser=5&hl=vi)
Một điều tôi thấy thú vị về những kết quả này là sự phân phối với một nhân viên dịch vụ được kiểm soát vẫn có đường cong hình chuông sau mức tăng đột biến ban đầu. Tôi đã kỳ vọng có mức tăng đột biến ban đầu lớn rồi sau đó giảm dần, tôi không mong đợi sẽ có đỉnh thứ hai trên đường cong.
Khi xem xét nguyên nhân có thể gây ra vấn đề này, tôi biết được rằng mặc dù trình chạy dịch vụ có thể đang kiểm soát trang, nhưng luồng của trang đó có thể không hoạt động. Trình duyệt thực hiện việc này để tiết kiệm tài nguyên – rõ ràng là bạn không cần mỗi service worker cho mọi trang web bạn từng truy cập để hoạt động và sẵn sàng kịp thời. Điều này giải thích phần đuôi của phân phối. Đối với một số người dùng, đã có sự chậm trễ khi luồng trình chạy dịch vụ khởi động.
Như bạn có thể thấy trong quá trình phân phối, ngay cả với sự chậm trễ ban đầu này, các trình duyệt có trình chạy dịch vụ đã phân phối nội dung nhanh hơn các trình duyệt đi qua mạng.
Sau đây là giao diện của nội dung trên thiết bị di động:
![Thời gian cho đến khi phân phối bản vẽ đầu tiên trên thiết bị di động](https://web.developers.google.cn/static/case-studies/service-worker-perf/image/time-first-paint-distrib-4ae7b2dd6775c.png?authuser=5&hl=vi)
Mặc dù số lần vẽ đầu tiên gần như ngay lập tức vẫn gia tăng đáng kể, nhưng phần đuôi đã lớn hơn và dài hơn một chút. Điều này có thể là do trên thiết bị di động, việc bắt đầu một luồng trình chạy dịch vụ ở trạng thái rảnh mất nhiều thời gian hơn so với trên máy tính. Điều này cũng giải thích lý do sự chênh lệch giữa thời gian firstpaint
trung bình không lớn như tôi mong đợi (thảo luận ở trên).
"...trên thiết bị di động, việc bắt đầu một luồng trình chạy dịch vụ ở trạng thái rảnh sẽ mất nhiều thời gian hơn so với trên máy tính."
Dưới đây là bảng chi tiết từ các biến thể sau đây về thời gian hiển thị đầu tiên trung bình trên thiết bị di động và máy tính được nhóm theo trạng thái của trình chạy dịch vụ:
Thời gian trung bình để hiển thị đầu tiên (mili giây) | ||
---|---|---|
Trạng thái trình chạy dịch vụ | Máy tính | Di động |
Đã kiểm soát | 583 | 1634 |
Được hỗ trợ (không được kiểm soát) | 912 | 1933 |
Mặc dù việc tạo những hình ảnh phân phối này mất nhiều thời gian và công sức hơn một chút so với việc tạo báo cáo tuỳ chỉnh trong Google Analytics, nhưng chúng cho chúng tôi hiểu rõ hơn nhiều về cách trình thực thi dịch vụ ảnh hưởng đến hiệu suất của trang web so với khi chỉ sử dụng mức trung bình.
Tác động khác từ Service Workers
Ngoài tác động đến hiệu suất, trình chạy dịch vụ cũng tác động đến trải nghiệm người dùng theo một số cách khác có thể đo lường được với Google Analytics.
Xem không cần mạng
Trình chạy dịch vụ cho phép người dùng tương tác với trang web của bạn khi không có mạng. Tuy nhiên, đối với một ứng dụng web tiến bộ, việc xác định mức độ quan trọng trong trường hợp này phụ thuộc phần lớn vào mức độ sử dụng hiện tại. Nhưng làm cách nào để chúng tôi đo lường điều đó?
Việc gửi dữ liệu đến Google Analytics cần có kết nối Internet, nhưng không yêu cầu gửi dữ liệu vào đúng thời điểm xảy ra hoạt động tương tác. Google Analytics hỗ trợ gửi dữ liệu lượt tương tác sau khi thực hiện bằng cách chỉ định chênh lệch thời gian (thông qua tham số qt
).
Trong hai năm qua, IOWA đã sử dụng tập lệnh trình chạy dịch vụ nhằm phát hiện các lượt truy cập không thành công vào Google Analytics khi người dùng không có kết nối mạng và phát lại sau đó với thông số qt
.
Để theo dõi xem người dùng đang hoạt động trực tuyến hay ngoại tuyến, chúng tôi đã tạo một phương diện tuỳ chỉnh có tên là Trực tuyến rồi đặt phương diện đó thành giá trị navigator.onLine
, sau đó lắng nghe sự kiện online
và offline
rồi cập nhật phương diện cho phù hợp.
Để giúp bạn nắm được mức độ phổ biến của việc người dùng không có kết nối mạng trong khi sử dụng IOWA, chúng tôi đã tạo một phân khúc nhắm đến những người dùng có ít nhất một lượt tương tác ngoại tuyến. Trên thực tế, đó là gần 5% số người dùng.
Thông báo đẩy
Trình chạy dịch vụ cho phép người dùng chọn nhận thông báo đẩy. Trong IOWA, người dùng được thông báo khi một phiên trong lịch biểu của họ sắp bắt đầu.
Giống như mọi hình thức thông báo, quan trọng là bạn phải tìm được sự cân bằng giữa việc mang lại giá trị cho người dùng và làm phiền họ. Để hiểu rõ hơn điều gì đang xảy ra, điều quan trọng là phải theo dõi xem người dùng có đang chọn nhận những thông báo này hay không, liệu họ có tương tác với chúng khi đến nơi hay không và có bất kỳ người dùng nào trước đó đã chọn nhận thay đổi tùy chọn của họ và chọn không nhận thông báo hay không.
Trong IOWA, chúng tôi chỉ gửi thông báo liên quan đến lịch biểu cá nhân hoá của người dùng. Chỉ người dùng đã đăng nhập mới có thể tạo thông báo. Việc này đã giới hạn nhóm người dùng có thể nhận thông báo cho người dùng đã đăng nhập (được theo dõi qua một phương diện tuỳ chỉnh có tên là Đã đăng nhập) có trình duyệt hỗ trợ thông báo đẩy (được theo dõi qua một phương diện tuỳ chỉnh khác có tên là Quyền thông báo).
Báo cáo sau đây dựa trên chỉ số Số người dùng và phương diện tuỳ chỉnh Quyền gửi thông báo. Các báo cáo này được phân đoạn theo những người dùng đã đăng nhập vào một thời điểm nào đó và có trình duyệt hỗ trợ thông báo đẩy.
Thật tuyệt khi biết rằng hơn một nửa số người dùng đã đăng nhập của chúng tôi đã chọn nhận thông báo đẩy.
Biểu ngữ cài đặt ứng dụng
Nếu một ứng dụng web tiến trình đáp ứng các tiêu chí và được người dùng thường xuyên sử dụng, thì người dùng đó có thể thấy một biểu ngữ cài đặt ứng dụng, nhắc họ thêm ứng dụng vào màn hình chính.
Trong IOWA, chúng tôi theo dõi tần suất mà những lời nhắc này hiển thị cho người dùng (và liệu chúng có được chấp nhận hay không) bằng mã sau:
window.addEventListener('beforeinstallprompt', function(event) {
// Tracks that the user saw a prompt.
ga('send', 'event', {
eventCategory: 'installprompt',
eventAction: 'fired'
});
event.userChoice.then(function(choiceResult) {
// Tracks the users choice.
ga('send', 'event', {
eventCategory: 'installprompt',
// `choiceResult.outcome` will be 'accepted' or 'dismissed'.
eventAction: choiceResult.outcome,
// `choiceResult.platform` will be 'web' or 'android' if the prompt was
// accepted, or '' if the prompt was dismissed.
eventLabel: choiceResult.platform
});
});
});
Trong số người dùng nhìn thấy biểu ngữ cài đặt ứng dụng, có khoảng 10% chọn thêm biểu ngữ này vào màn hình chính.
Tính năng theo dõi có thể cải thiện (cho lần tiếp theo)
Dữ liệu phân tích mà chúng tôi thu thập được từ IOWA năm nay rất hữu ích. Tuy nhiên, những khoảnh khắc bỏ ngỏ luôn mang đến những lỗ hổng nhỏ và cơ hội để cải thiện mọi thứ cho lần sau. Sau khi kết thúc bản phân tích năm nay, sau đây là hai điều tôi mong muốn chúng ta thay đổi để những độc giả muốn triển khai chiến lược tương tự có thể cân nhắc:
1. Theo dõi các sự kiện khác liên quan đến trải nghiệm tải
Chúng tôi đã theo dõi một số sự kiện tương ứng với một chỉ số kỹ thuật (ví dụ: HTMLImportsLoaded, WebComponentsReady, v.v.), nhưng vì rất nhiều tải được thực hiện không đồng bộ, điểm mà các sự kiện này kích hoạt không nhất thiết tương ứng với một thời điểm cụ thể trong trải nghiệm tải tổng thể.
Sự kiện chính liên quan đến tải mà chúng tôi không theo dõi (nhưng ước gì chúng tôi có) là thời điểm màn hình chờ biến mất và người dùng có thể xem nội dung trang.
2. Lưu trữ mã ứng dụng khách Analytics trong IndexedDB
Theo mặc định, analytics.js lưu trữ trường mã ứng dụng khách trong cookie của trình duyệt; rất tiếc là tập lệnh trình chạy dịch vụ không thể truy cập vào cookie.
Điều này đã gây trở ngại cho chúng tôi khi cố gắng triển khai tính năng theo dõi thông báo. Chúng tôi muốn gửi một sự kiện từ trình chạy dịch vụ (thông qua Measurement Protocol) mỗi khi gửi thông báo cho người dùng, sau đó theo dõi tỷ lệ tương tác lại thành công của thông báo đó nếu người dùng đã nhấp vào thông báo và quay lại ứng dụng.
Mặc dù có thể theo dõi mức độ thành công của các thông báo nói chung thông qua thông số chiến dịch utm_source
, nhưng chúng tôi không thể liên kết một phiên tương tác lại cụ thể với người dùng cụ thể.
Điều chúng tôi có thể làm để khắc phục hạn chế này là lưu trữ ID ứng dụng khách thông qua IndexedDB trong mã theo dõi, sau đó tập lệnh trình chạy dịch vụ có thể truy cập giá trị đó.
3. Cho phép trình chạy dịch vụ báo cáo trạng thái trực tuyến/ngoại tuyến
Việc kiểm tra navigator.onLine
sẽ cho bạn biết liệu trình duyệt của bạn có thể kết nối với bộ định tuyến hoặc mạng cục bộ hay không, nhưng không nhất thiết cho biết liệu người dùng có kết nối thực hay không. Và vì tập lệnh của trình chạy dịch vụ phân tích ngoại tuyến của chúng tôi chỉ phát lại các lượt truy cập không thành công (mà không sửa đổi hoặc đánh dấu chúng là không thành công), nên có thể chúng tôi đã báo cáo thiếu mức sử dụng ngoại tuyến.
Trong tương lai, chúng ta nên theo dõi cả trạng thái của navigator.onLine
cũng như liệu lượt truy cập có được trình chạy dịch vụ phát lại do lỗi mạng ban đầu hay không. Điều này sẽ giúp chúng tôi hiểu chính xác hơn về việc sử dụng ngoại tuyến thực tế.
Kết thúc
Nghiên cứu điển hình này đã chỉ ra rằng việc sử dụng service worker thực sự cải thiện hiệu suất tải của ứng dụng web Google I/O trên một loạt trình duyệt, mạng và thiết bị. Nó cũng chỉ ra rằng khi xem xét phân phối dữ liệu tải trên hàng loạt trình duyệt, mạng và thiết bị, bạn sẽ hiểu rõ hơn về cách công nghệ này xử lý các tình huống thực tế và bạn khám phá các đặc điểm hiệu suất mà bạn có thể không mong đợi.
Dưới đây là một số điểm chính cần ghi nhớ trong nghiên cứu của IOWA:
- Trung bình, các trang tải nhanh hơn khá nhiều khi một trình chạy dịch vụ kiểm soát trang so với khi không có một trình chạy dịch vụ, cho cả khách truy cập mới và khách truy cập quay lại.
- Lượt truy cập vào các trang do một trình chạy dịch vụ kiểm soát được tải gần như ngay lập tức đối với nhiều người dùng.
- Khi không hoạt động, Service worker mất một chút thời gian để khởi động. Tuy nhiên, một trình chạy dịch vụ không hoạt động vẫn hoạt động tốt hơn là không có trình chạy dịch vụ nào.
- Thời gian khởi động của một trình chạy dịch vụ không hoạt động trên thiết bị di động lâu hơn trên máy tính.
Mặc dù mức tăng hiệu suất quan sát được trong một ứng dụng cụ thể thường hữu ích khi báo cáo cho cộng đồng nhà phát triển lớn hơn, nhưng điều quan trọng cần nhớ là những kết quả này dành riêng cho loại trang web IOWA (trang web sự kiện) và loại đối tượng IOWA có (chủ yếu là nhà phát triển).
Nếu đang triển khai service worker trong ứng dụng của mình, thì bạn cần phải triển khai chiến lược đo lường của riêng mình để có thể đánh giá hiệu suất của riêng mình và ngăn chặn sự hồi quy trong tương lai. Nếu bạn làm được điều đó, hãy chia sẻ kết quả của bạn để mọi người đều được hưởng lợi!
Chú thích chân trang
- Việc so sánh hiệu suất của việc triển khai bộ nhớ đệm của trình chạy dịch vụ với hiệu suất của trang web chỉ có bộ nhớ đệm HTTP là không công bằng. Vì đang tối ưu hoá IOWA cho trình chạy dịch vụ, nên chúng tôi không dành nhiều thời gian để tối ưu hoá cho bộ nhớ đệm HTTP. Nếu chúng tôi có, kết quả có lẽ đã khác. Để tìm hiểu thêm về cách tối ưu hoá trang web của bạn cho bộ nhớ đệm HTTP, hãy đọc bài viết Tối ưu hoá nội dung một cách hiệu quả.
- Tuỳ thuộc vào cách trang web của bạn tải kiểu và nội dung, có thể trình duyệt có khả năng tô trước khi nội dung hoặc kiểu được cung cấp. Trong những trường hợp như vậy,
firstpaint
có thể tương ứng với một màn hình trắng trống. Nếu sử dụngfirstpaint
, bạn phải đảm bảo mã này tương ứng với một điểm có ý nghĩa trong quá trình tải tài nguyên của trang web. - Về mặt kỹ thuật, chúng tôi có thể gửi lượt truy cập thời gian (là không tương tác theo mặc định) để thu thập thông tin này thay vì một sự kiện. Trên thực tế, các lượt truy cập thời gian đã được thêm riêng vào Google Analytics để theo dõi các chỉ số tải như thế này; tuy nhiên, các lượt truy cập theo thời gian được lấy mẫu rất nhiều tại thời điểm xử lý và không thể sử dụng giá trị của chúng trong phân đoạn. Với những hạn chế hiện tại này, các sự kiện không tương tác vẫn phù hợp hơn.
- Để hiểu rõ hơn về phạm vi cần cung cấp thứ nguyên tùy chỉnh trong Google Analytics, hãy tham khảo phần Thứ nguyên tùy chỉnh trong trung tâm trợ giúp Analytics. Việc hiểu mô hình dữ liệu Google Analytics, bao gồm người dùng, phiên hoạt động và lượt tương tác (lượt truy cập) cũng rất quan trọng. Để tìm hiểu thêm, hãy xem bài học về Mô hình dữ liệu của Google Analytics trong Học viện Analytics.
- Điều này không tính đến các tài nguyên được tải từng phần sau sự kiện tải.