API thời gian người dùng

Tìm hiểu ứng dụng web của bạn

Alex Danilo

Các ứng dụng web có hiệu suất cao rất quan trọng đối với trải nghiệm người dùng tuyệt vời. Khi các ứng dụng web ngày càng trở nên phức tạp hơn, việc hiểu rõ tác động của hiệu suất là rất quan trọng để tạo ra trải nghiệm hấp dẫn. Trong vài năm qua, một số API đã xuất hiện trong trình duyệt để giúp phân tích hiệu suất của mạng, thời gian tải, v.v. nhưng không nhất thiết phải cung cấp thông tin chi tiết cũng như đủ độ linh hoạt để tìm ra nguyên nhân đang làm chậm ứng dụng của bạn. Nhập API Thời gian người dùng. API này cung cấp cơ chế mà bạn có thể sử dụng để đo lường ứng dụng web nhằm xác định nơi ứng dụng dành thời gian. Trong bài viết này, chúng ta sẽ đề cập đến API cùng các ví dụ về cách sử dụng API.

Bạn không thể tối ưu hoá những yếu tố mà bạn không thể đo lường

Bước đầu tiên để tăng tốc một ứng dụng web chậm là tìm ra nơi sử dụng thời gian. Đo lường tác động theo thời gian của các vùng mã JavaScript là cách lý tưởng để xác định các điểm nóng, đây là bước đầu tiên trong việc tìm cách cải thiện hiệu suất. May mắn là API Thời gian người dùng cung cấp cách bạn có thể chèn lệnh gọi API tại các phần khác nhau của JavaScript, sau đó trích xuất dữ liệu thời gian chi tiết có thể dùng để giúp bạn tối ưu hoá.

Thời gian phân giải cao và now()

Độ chính xác là một yếu tố cơ bản của việc đo lường thời gian chính xác. Trước đây, chúng ta có thời gian dựa trên phép đo tính bằng mili giây thì không sao, nhưng việc xây dựng một trang web 60 FPS không bị giật có nghĩa là mỗi khung hình cần được vẽ trong 16 mili giây. Vì vậy, khi bạn chỉ có độ chính xác tính bằng mili giây, nó sẽ thiếu độ chính xác cần thiết để phân tích hiệu quả. Nhập Thời gian độ phân giải cao, một loại thời gian mới được tích hợp vào các trình duyệt hiện đại. Thời gian độ phân giải cao cung cấp cho chúng tôi dấu thời gian dạng dấu phẩy động có độ phân giải chính xác đến độ phân giải micrô giây - tốt hơn hàng nghìn lần so với trước đây.

Để xem thời gian hiện tại trong ứng dụng web của bạn, hãy gọi phương thức now(). Phương thức này tạo thành tiện ích của giao diện Hiệu suất. Mã sau đây cho biết cách thực hiện việc đó:

var myTime = window.performance.now();

Có một giao diện khác tên là PerformanceTiming. Giao diện này cung cấp một số thời gian khác nhau liên quan đến cách ứng dụng web của bạn được tải. Phương thức now() trả về thời gian đã trôi qua kể từ thời điểm navigationStart trong PerformanceTiming xảy ra.

Loại DOMHighResTimeStamp

Khi cố gắng tính thời gian cho các ứng dụng web trong quá khứ, bạn nên sử dụng một tham số như Date.now() để trả về DOMTimeStamp. DOMTimeStamp trả về giá trị là số nguyên mili giây. Để cung cấp độ chính xác cao hơn cần thiết cho thời gian Độ phân giải cao, chúng tôi đã ra mắt một loại mới có tên DOMHighResTimeStamp. Loại này là một giá trị dấu phẩy động cũng trả về thời gian theo mili giây. Tuy nhiên, vì đây là dấu phẩy động nên giá trị này có thể biểu thị tỷ lệ mili giây, do đó có thể mang lại độ chính xác là 1/100 mili giây.

Giao diện thời gian người dùng

Giờ đây, khi chúng ta có các dấu thời gian có độ phân giải cao, hãy sử dụng giao diện Thời gian người dùng để lấy thông tin thời gian.

Giao diện Thời gian người dùng cung cấp các hàm cho phép chúng ta gọi phương thức tại các vị trí khác nhau trong ứng dụng. Các hàm này có thể cung cấp đường dẫn breadcrumb kiểu Hansel và Gretel để cho phép chúng ta theo dõi thời gian đã sử dụng.

Sử dụng mark()

Phương thức mark() là công cụ chính trong bộ công cụ phân tích thời gian của chúng tôi. Việc mark() làm là lưu trữ dấu thời gian cho chúng ta. Điều cực kỳ hữu ích về mark() là chúng ta có thể đặt tên cho dấu thời gian, đồng thời API sẽ ghi nhớ tên và dấu thời gian dưới dạng một đơn vị duy nhất.

Việc gọi mark() tại các vị trí khác nhau trong ứng dụng của bạn cho phép bạn biết được bạn mất bao nhiêu thời gian để đạt đến "dấu" đó trong ứng dụng web.

Bản đặc tả kỹ thuật nêu rõ một số tên đề xuất cho những nhãn hiệu có thể thú vị và khá dễ hiểu, chẳng hạn như mark_fully_loaded, mark_fully_visible,mark_above_the_fold, v.v.

Ví dụ: chúng ta có thể đặt nhãn cho thời điểm ứng dụng được tải đầy đủ bằng cách dùng mã sau:

window.performance.mark('mark_fully_loaded');

Bằng cách đặt các dấu hiệu được đặt tên trong ứng dụng web của mình, chúng tôi có thể thu thập hàng loạt dữ liệu thời gian và phân tích dữ liệu đó một cách tuỳ ý để tìm ra hoạt động của ứng dụng và thời điểm hoạt động.

Tính số đo bằng measure()

Sau khi đặt một loạt các dấu thời gian, bạn sẽ muốn biết thời gian đã trôi qua giữa các dấu thời gian đó. Hãy sử dụng phương thức measure() để thực hiện việc này.

Phương thức measure() tính toán thời gian đã trôi qua giữa các dấu, đồng thời có thể đo thời gian giữa điểm đánh dấu và tên sự kiện đã biết trong giao diện PerformanceTiming.

Ví dụ: bạn có thể tính ra thời gian từ khi DOM hoàn tất cho đến khi trạng thái ứng dụng của bạn được tải đầy đủ bằng cách sử dụng mã như:

window.performance.measure('measure_load_from_dom', 'domComplete', 'mark_fully_loaded');

Khi bạn gọi measure(), phương thức này sẽ lưu trữ kết quả độc lập với các nhãn bạn đã đặt để bạn có thể truy xuất các kết quả đó sau. Bằng cách lưu trữ thời gian vắng mặt khi ứng dụng của bạn chạy, ứng dụng vẫn phản hồi và bạn có thể kết xuất tất cả dữ liệu sau khi ứng dụng hoàn thành một số công việc để có thể phân tích sau.

Loại bỏ dấu bằng clearMarks()

Đôi khi, việc loại bỏ một loạt nhãn mà bạn đã thiết lập sẽ rất hữu ích. Ví dụ: bạn có thể thực hiện chạy hàng loạt trên ứng dụng web của mình và vì vậy bạn muốn bắt đầu lại mỗi lần chạy.

Bạn có thể dễ dàng loại bỏ các nhãn mà bạn đã thiết lập bằng cách gọi clearMarks().

Vì vậy, mã ví dụ bên dưới sẽ làm mất đi tất cả các nhãn hiện có, vì vậy bạn có thể thiết lập lại thời gian nếu muốn.

window.performance.clearMarks();

Tất nhiên, có một số trường hợp mà bạn có thể không muốn xoá hết các điểm. Vì vậy, nếu muốn loại bỏ các dấu hiệu cụ thể, bạn có thể chỉ cần đặt tên của dấu mà bạn muốn xoá. Ví dụ: mã dưới đây:

window.peformance.clearMarks('mark_fully_loaded');

bỏ dấu chúng ta đã đặt trong ví dụ đầu tiên, đồng thời để lại bất kỳ dấu nào khác mà chúng ta đã đặt không thay đổi.

Bạn cũng nên loại bỏ mọi biện pháp mình đã thực hiện và có một phương thức tương ứng để thực hiện việc đó có tên là clearMeasures(). API này hoạt động giống như clearMarks(), nhưng thay vào đó hoạt động trên mọi phép đo mà bạn đã thực hiện. Ví dụ: mã:

window.performance.clearMeasures('measure_load_from_dom');

sẽ xoá thông tin đo lường mà chúng ta đã thực hiện trong ví dụ về measure() ở trên. Nếu bạn muốn xoá mọi giá trị đo lường, thì thao tác này cũng giống như clearMarks(), ở chỗ bạn chỉ cần gọi clearMeasures() mà không có đối số.

Lấy dữ liệu về thời gian

Mọi việc đều tốt và tốt để đánh dấu và đo các khoảng thời gian, nhưng vào một thời điểm nào đó bạn muốn có được dữ liệu thời gian đó để thực hiện một số phân tích. Việc này cũng thực sự đơn giản. Bạn chỉ cần sử dụng giao diện PerformanceTimeline.

Ví dụ: phương thức getEntriesByType() cho phép chúng ta nhận tất cả thời gian đánh dấu hoặc tất cả các số đo hết thời gian chờ dưới dạng danh sách để chúng ta có thể lặp lại và phân tích dữ liệu. Điều tuyệt vời là danh sách được trả về theo thứ tự thời gian, vì vậy bạn có thể thấy các dấu theo thứ tự được hiển thị trong ứng dụng web của mình.

Mã dưới đây:

var items = window.performance.getEntriesByType('mark');

sẽ trả về cho chúng tôi danh sách tất cả các dấu đã được nhấn trong ứng dụng web, ngoài ra còn có mã:

var items = window.performance.getEntriesByType('measure');

trả về cho chúng tôi danh sách tất cả các biện pháp chúng tôi đã thực hiện.

Bạn cũng có thể lấy lại danh sách các mục nhập bằng cách sử dụng tên cụ thể bạn đã cấp cho các mục đó. Vì vậy, ví dụ như mã:

var items = window.performance.getEntriesByName('mark_fully_loaded');

sẽ trả về cho chúng tôi danh sách có một mục trong đó chứa dấu thời gian "mark_fully_loading" trong thuộc tính startTime.

Định thời gian cho một yêu cầu XHR (ví dụ)

Bây giờ, chúng ta đã hiểu rõ về API Thời gian người dùng, chúng ta có thể sử dụng API này để phân tích thời gian tất cả XMLHttpRequests trong ứng dụng web.

Trước tiên, chúng ta sẽ sửa đổi tất cả yêu cầu send() để phát một lệnh gọi hàm thiết lập các nhãn, đồng thời thay đổi lệnh gọi lại thành công bằng một lệnh gọi hàm đặt một dấu khác, sau đó tạo chỉ số đo lường thời gian thực hiện yêu cầu.

XMLHttpRequest thông thường sẽ có dạng như sau:

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  do_something(e.responseText);
}
myReq.send();

Trong ví dụ này, chúng ta sẽ thêm một bộ đếm toàn cầu để theo dõi số lượng yêu cầu cũng như dùng bộ đếm này để lưu trữ chỉ số đo lường cho mỗi yêu cầu được đưa ra. Mã để thực hiện việc này trông giống như sau:

var reqCnt = 0;

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  window.performance.mark('mark_end_xhr');
  reqCnt++;
  window.performance.measure('measure_xhr_' + reqCnt, 'mark_start_xhr', 'mark_end_xhr');
  do_something(e.responseText);
}
window.performance.mark('mark_start_xhr');
myReq.send();

Đoạn mã ở trên tạo ra một phép đo có một giá trị tên duy nhất cho mỗi XMLHttpRequest mà chúng tôi gửi. Chúng ta giả định rằng các yêu cầu chạy theo trình tự – mã cho các yêu cầu song song sẽ cần phức tạp hơn một chút để xử lý các yêu cầu trả về không đúng thứ tự, chúng ta sẽ để độc giả làm một bài tập.

Sau khi ứng dụng web đã thực hiện một loạt yêu cầu, chúng ta có thể kết xuất tất cả yêu cầu đó vào bảng điều khiển bằng mã dưới đây:

var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
  var req = items[i];
  console.log('XHR ' + req.name + ' took ' + req.duration + 'ms');
}

Kết luận

API thời gian người dùng cung cấp cho bạn rất nhiều công cụ tuyệt vời để áp dụng cho bất kỳ khía cạnh nào của ứng dụng web. Bạn có thể dễ dàng thu hẹp các điểm nóng trong ứng dụng bằng cách rắc các lệnh gọi API trong toàn bộ ứng dụng web và xử lý hậu kỳ dữ liệu thời gian được tạo để giúp bạn hiểu rõ nơi sử dụng thời gian. Nhưng nếu trình duyệt của bạn không hỗ trợ API này thì sao? Không vấn đề gì, bạn có thể tìm thấy một polyfill tuyệt vời tại đây mô phỏng API thực sự hiệu quả và cũng hoạt động hiệu quả trên webpagetest.org. Vậy bạn còn chờ gì nữa? Hãy dùng thử API Thời gian người dùng trên các ứng dụng của bạn ngay bây giờ, bạn sẽ tìm ra cách tăng tốc chúng và người dùng của bạn sẽ cảm ơn bạn vì đã giúp họ có trải nghiệm tốt hơn rất nhiều.