Gần đây, bạn có thấy cảnh báo như sau trong Bảng điều khiển dành cho nhà phát triển trong Chrome và thắc mắc đó là cảnh báo gì không?
(index):34 A Parser-blocking, cross-origin script,
https://paul.kinlan.me/ad-inject.js, is invoked via document.write().
This may be blocked by the browser if the device has poor network connectivity.
Khả năng kết hợp là một trong những thế mạnh lớn của web, cho phép chúng ta dễ dàng tích hợp với các dịch vụ do bên thứ ba xây dựng để tạo ra các sản phẩm mới tuyệt vời! Một trong những nhược điểm của khả năng kết hợp là nó ngụ ý trách nhiệm chia sẻ đối với trải nghiệm người dùng. Nếu quá trình tích hợp không tối ưu, trải nghiệm người dùng sẽ bị ảnh hưởng tiêu cực.
Một nguyên nhân đã biết gây ra hiệu suất kém là việc sử dụng document.write()
bên trong các trang, cụ thể là những trường hợp sử dụng chèn tập lệnh. Tuy vô hại như sau, nhưng nó có thể gây ra vấn đề thực sự cho người dùng.
document.write('<script src="https://example.com/ad-inject.js"></script>');
Trước khi có thể hiển thị một trang, trình duyệt phải tạo cây DOM bằng cách phân tích cú pháp mã đánh dấu HTML. Bất cứ khi nào trình phân tích cú pháp gặp một tập lệnh, trình phân tích cú pháp sẽ phải dừng và thực thi tập lệnh đó trước khi có thể tiếp tục phân tích cú pháp HTML. Nếu tập lệnh chèn một tập lệnh khác một cách linh động, thì trình phân tích cú pháp buộc phải chờ lâu hơn để tải tài nguyên xuống, điều này có thể gây ra một hoặc nhiều lượt truy cập mạng và làm chậm thời gian hiển thị lần đầu của trang
Đối với người dùng có kết nối chậm, chẳng hạn như 2G, các tập lệnh bên ngoài được chèn động thông qua document.write()
có thể làm chậm quá trình hiển thị nội dung trang chính trong vài chục giây, hoặc khiến trang không thể tải hoặc tải quá lâu nên người dùng bỏ cuộc. Dựa trên thông tin đo lường trong Chrome, chúng tôi nhận thấy rằng các trang có tập lệnh của bên thứ ba được chèn qua document.write()
thường tải chậm hơn hai lần so với các trang khác trên 2G.
Chúng tôi đã thu thập dữ liệu từ một thử nghiệm thực địa kéo dài 28 ngày trên 1% người dùng Chrome phiên bản ổn định, chỉ dành cho người dùng có kết nối 2G. Chúng tôi nhận thấy 7, 6% tổng số lượt tải trang trên 2G bao gồm ít nhất một tập lệnh chặn trình phân tích cú pháp trên nhiều trang web đã được chèn qua document.write()
trong tài liệu cấp cao nhất. Do chặn tải các tập lệnh này, chúng tôi nhận thấy những điểm cải tiến sau đây đối với các lượt tải đó:
- 10% số lượt tải trang đạt đến lần vẽ nội dung đầu tiên (một xác nhận trực quan cho người dùng rằng trang đang tải hiệu quả), 25% số lượt tải trang đạt đến trạng thái được phân tích cú pháp đầy đủ và 10% số lượt tải lại ít hơn, cho thấy sự giảm bớt sự khó chịu của người dùng.
- Giảm 21% thời gian trung bình (nhanh hơn một giây) cho đến khi hiển thị nội dung đầu tiên
- Giảm 38% thời gian trung bình để phân tích cú pháp một trang, tương đương với việc cải thiện gần 6 giây, giúp giảm đáng kể thời gian hiển thị nội dung quan trọng đối với người dùng.
Dựa trên dữ liệu này, Chrome, bắt đầu từ phiên bản 55, sẽ thay mặt tất cả người dùng can thiệp khi phát hiện mẫu đã biết là xấu này bằng cách thay đổi cách xử lý document.write()
trong Chrome (Xem Trạng thái Chrome).
Cụ thể, Chrome sẽ không thực thi các phần tử <script>
được chèn thông qua document.write()
khi tất cả các điều kiện sau đây được đáp ứng:
- Người dùng đang sử dụng kết nối chậm, đặc biệt là khi người dùng sử dụng 2G. (Trong tương lai, thay đổi này có thể được áp dụng cho những người dùng khác có kết nối chậm, chẳng hạn như 3G chậm hoặc Wi-Fi chậm.)
document.write()
nằm trong tài liệu cấp cao nhất. Biện pháp can thiệp này không áp dụng cho các tập lệnh document.writer trong iframe vì chúng không chặn quá trình hiển thị trang chính.- Tập lệnh trong
document.write()
đang chặn trình phân tích cú pháp. Các tập lệnh có thuộc tính "async
" hoặc "defer
" sẽ vẫn thực thi. - Tập lệnh không được lưu trữ trên cùng một trang web. Nói cách khác, Chrome sẽ không can thiệp vào các tập lệnh có eTLD+1 khớp (ví dụ: một tập lệnh được lưu trữ trên js.example.org được chèn vào www.example.org).
- Tập lệnh chưa có trong bộ nhớ đệm HTTP của trình duyệt. Các tập lệnh trong bộ nhớ đệm sẽ không gây trễ mạng và vẫn sẽ thực thi.
- Yêu cầu cho trang không phải là tải lại. Chrome sẽ không can thiệp nếu người dùng kích hoạt một lượt tải lại và sẽ thực thi trang như bình thường.
Đoạn mã của bên thứ ba đôi khi sử dụng document.write()
để tải tập lệnh.
May mắn thay, hầu hết các bên thứ ba đều cung cấp các phương án tải không đồng bộ, cho phép các tập lệnh của bên thứ ba tải mà không chặn việc hiển thị nội dung còn lại trên trang.
Làm cách nào để khắc phục lỗi này?
Câu trả lời đơn giản này là không chèn tập lệnh bằng document.write()
. Chúng tôi duy trì một nhóm các dịch vụ đã biết để hỗ trợ trình tải không đồng bộ mà bạn nên tiếp tục kiểm tra.
Nếu nhà cung cấp của bạn không có trong danh sách và hỗ trợ tính năng tải tập lệnh không đồng bộ, vui lòng cho chúng tôi biết để chúng tôi có thể cập nhật trang nhằm giúp tất cả người dùng.
Nếu nhà cung cấp của bạn không hỗ trợ khả năng tải tập lệnh không đồng bộ vào trang, bạn nên liên hệ với họ và cho chúng tôi và họ biết mức độ ảnh hưởng.
Nếu nhà cung cấp cung cấp cho bạn một đoạn mã bao gồm document.write()
, bạn có thể thêm thuộc tính async
vào phần tử tập lệnh hoặc thêm các phần tử tập lệnh bằng API DOM như document.appendChild()
hoặc parentNode.insertBefore()
.
Cách phát hiện khi nào trang web của bạn bị ảnh hưởng
Có rất nhiều tiêu chí để xác định việc quy định hạn chế có được thực thi hay không. Vậy làm cách nào để bạn biết liệu mình có bị ảnh hưởng hay không?
Phát hiện thời điểm người dùng đang dùng mạng 2G
Để hiểu được tác động tiềm ẩn của thay đổi này, trước tiên, bạn cần biết được có bao nhiêu người dùng sẽ sử dụng mạng 2G. Bạn có thể phát hiện loại và tốc độ mạng hiện tại của người dùng bằng cách sử dụng API Thông tin mạng có trong Chrome, sau đó gửi thông báo cho hệ thống phân tích hoặc hệ thống Chỉ số người dùng thực (RUM).
if(navigator.connection &&
navigator.connection.type === 'cellular' &&
navigator.connection.downlinkMax <= 0.115) {
// Notify your service to indicate that you might be affected by this restriction.
}
Phát hiện cảnh báo trong Công cụ của Chrome cho nhà phát triển
Kể từ Chrome 53, Công cụ cho nhà phát triển sẽ đưa ra cảnh báo đối với các câu lệnh document.write()
có vấn đề. Cụ thể, nếu yêu cầu document.write()
đáp ứng các tiêu chí từ 2 đến 5 (Chrome bỏ qua tiêu chí kết nối khi gửi cảnh báo này), thì cảnh báo sẽ có dạng như sau:
Việc thấy cảnh báo trong Công cụ cho nhà phát triển Chrome là rất tuyệt, nhưng làm cách nào để phát hiện điều này trên quy mô lớn? Bạn có thể kiểm tra các tiêu đề HTTP được gửi đến máy chủ của mình khi biện pháp can thiệp xảy ra.
Kiểm tra tiêu đề HTTP trên tài nguyên tập lệnh
Khi một tập lệnh được chèn thông qua document.write
bị chặn, Chrome sẽ gửi tiêu đề sau đến tài nguyên được yêu cầu:
Intervention: <https://shorturl/relevant/spec>;
Khi phát hiện một tập lệnh được chèn thông qua document.write
và có thể bị chặn trong nhiều trường hợp, Chrome có thể gửi:
Intervention: <https://shorturl/relevant/spec>; level="warning"
Tiêu đề can thiệp sẽ được gửi trong yêu cầu GET cho tập lệnh (không đồng bộ trong trường hợp có can thiệp thực tế).
Tương lai nắm giữ điều gì?
Kế hoạch ban đầu là thực thi biện pháp can thiệp này khi chúng tôi phát hiện các tiêu chí đang được đáp ứng. Chúng tôi bắt đầu bằng cách chỉ hiển thị cảnh báo trong Bảng điều khiển dành cho nhà phát triển trong Chrome 53. (Giai đoạn thử nghiệm beta là vào tháng 7 năm 2016. Chúng tôi dự kiến sẽ cung cấp phiên bản ổn định cho tất cả người dùng vào tháng 9 năm 2016.)
Chúng tôi sẽ can thiệp để chặn các tập lệnh được chèn cho người dùng 2G, dự kiến bắt đầu từ Chrome 54. Phiên bản này dự kiến sẽ được phát hành ổn định cho tất cả người dùng vào giữa tháng 10 năm 2016. Hãy xem mục Trạng thái của Chrome để biết thêm thông tin cập nhật.
Theo thời gian, chúng tôi sẽ can thiệp khi bất kỳ người dùng nào có kết nối chậm (tức là 3G hoặc Wi-Fi chậm). Làm theo mục Trạng thái của Chrome này.
Bạn muốn tìm hiểu thêm?
Để tìm hiểu thêm, hãy xem các tài nguyên bổ sung sau:
- Thông số kỹ thuật của biện pháp can thiệp document.write() và các vòng phản hồi của biện pháp này
- Trạng thái Chrome (sự can thiệp cho người dùng sử dụng mạng 2G)
- Trạng thái của Chrome (can thiệp hiệu quả cho người dùng có kết nối chậm)
- Tài liệu thiết kế
- Lý do khác cho việc này
- Ý định blink-dev để triển khai luồng