Cải thiện tính năng loại bỏ trang trong XMLHttpRequest() đồng bộ

Giảm thiểu việc di chuyển bị trễ

Joe Medley
Joe Medley

Thông thường, một trang hoặc ứng dụng có dữ liệu phân tích hoặc dữ liệu khác chưa được gửi tại thời điểm người dùng đóng nó. Để ngăn chặn mất dữ liệu, một số trang web sử dụng lệnh gọi đồng bộ đến XMLHttpRequest() để duy trì trạng thái mở của trang hoặc ứng dụng cho đến khi dữ liệu của trang hoặc ứng dụng đó được truyền đến máy chủ. Kỹ thuật này không chỉ có cách tiết kiệm dữ liệu hiệu quả hơn, mà còn tạo ra trải nghiệm không tốt cho người dùng khi trì hoãn việc đóng trang trong vòng vài giây.

Phương pháp này cần thay đổi và các trình duyệt đang phản hồi. Thông số kỹ thuật XMLHttpRequest() đã được dự kiến ngừng sử dụng và xoá. Chrome 80 thực hiện bước đầu tiên bằng cách không cho phép các lệnh gọi đồng bộ bên trong một số trình xử lý sự kiện, cụ thể là beforeunload, unload, pagehidevisibilitychange khi các lệnh gọi này được kích hoạt trong thao tác đóng. Gần đây, WebKit cũng xuất hiện một cam kết triển khai cùng một thay đổi về hành vi.

Trong bài viết này, tôi sẽ mô tả ngắn gọn các lựa chọn cho những người cần thời gian cập nhật trang web của họ và trình bày các lựa chọn thay thế cho XMLHttpRequest().

Chọn không tham gia tạm thời

Chrome không chỉ muốn rút phích cắm trên XMLHttpRequest(). Đó là lý do tại sao Chrome có sẵn một số tuỳ chọn chọn không tham gia tạm thời. Đối với các trang web trên Internet, bạn có thể dùng bản dùng thử theo nguyên gốc. Bằng cách này, bạn sẽ thêm một mã thông báo dành riêng cho từng nguồn gốc vào tiêu đề trang để có thể thực hiện các lệnh gọi XMLHttpRequest() đồng bộ. Tuỳ chọn này sẽ ngừng hoạt động ngay trước khi Chrome 89 ra mắt, vào khoảng tháng 3 năm 2021. Khách hàng Enterprise Chrome cũng có thể sử dụng cờ chính sách AllowSyncXHRInPageDismissal. Cờ này sẽ kết thúc cùng lúc.

Lựa chọn thay thế

Bất kể bạn gửi dữ liệu trở lại máy chủ bằng cách nào, tốt nhất là bạn không nên chờ cho đến khi huỷ tải trang để gửi tất cả dữ liệu cùng một lúc. Ngoài việc tạo ra trải nghiệm người dùng kém, quá trình gỡ tải còn không đáng tin cậy trên các trình duyệt hiện đại và có nguy cơ mất dữ liệu nếu xảy ra sự cố. Cụ thể, các sự kiện huỷ tải thường không kích hoạt trên trình duyệt trên thiết bị di động vì có nhiều cách để đóng một thẻ hoặc trình duyệt trên hệ điều hành trên thiết bị di động mà không có sự kiện unload kích hoạt. Với XMLHttpRequest(), việc sử dụng các tải trọng nhỏ là một lựa chọn. Bây giờ, đó là một yêu cầu. Cả hai lựa chọn thay thế đều có giới hạn tải lên là 64 KB cho mỗi ngữ cảnh, theo yêu cầu của quy cách.

Tìm nạp tính duy trì hoạt động

API Tìm nạp cung cấp một phương thức mạnh mẽ để xử lý các lượt tương tác với máy chủ và một giao diện nhất quán để sử dụng trên nhiều API nền tảng. Trong số các tuỳ chọn của lệnh này, có keepalive. Phương thức này đảm bảo rằng yêu cầu vẫn tiếp tục cho dù trang đặt yêu cầu đó có luôn mở hay không:

window.addEventListener('unload', {
  fetch('/siteAnalytics', {
    method: 'POST',
    body: getStatistics(),
    keepalive: true
  });
}

Phương thức fetch() có lợi thế là có thể kiểm soát tốt hơn nội dung được gửi đến máy chủ. Những gì tôi không cho thấy trong ví dụ này là fetch() cũng trả về một lời hứa sẽ giải quyết bằng đối tượng Response. Vì đang tìm cách tránh tải trang nên tôi chọn không làm gì với trang đó.

SendBeacon()

SendBeacon() thực sự sử dụng Tìm nạp API. Đó là lý do API này có cùng giới hạn tải trọng là 64 KB và cũng đảm bảo rằng một yêu cầu sẽ tiếp tục sau khi huỷ tải trang. Ưu điểm chính của phương pháp này là tính đơn giản. API này cho phép bạn gửi dữ liệu bằng một dòng mã:

window.addEventListener('unload', {
  navigator.sendBeacon('/siteAnalytics', getStatistics());
}

Kết luận

Với khả năng sử dụng fetch() ngày càng tăng trên các trình duyệt, hy vọng rằng XMLHttpRequest() sẽ bị xoá khỏi nền tảng web vào một thời điểm nào đó. Các nhà cung cấp trình duyệt đồng ý xoá trình duyệt này, nhưng sẽ cần thời gian. Việc ngừng sử dụng một trong những trường hợp sử dụng xấu nhất là bước đầu tiên giúp cải thiện trải nghiệm người dùng cho mọi người.

Ảnh chụp của Matthew Hamilton trên Unsplash