Intervensi terhadap document.write()

Apakah baru-baru ini Anda melihat peringatan seperti berikut pada Konsol Pengembang di Chrome dan ingin tahu apa itu?

(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.

Komposabilitas adalah salah satu kekuatan besar web, yang memungkinkan kita untuk berintegrasi dengan layanan yang dibuat oleh pihak ketiga untuk membuat produk baru yang hebat! paket Premium AI kelemahan dari komposabilitas adalah bahwa hal ini menyiratkan tanggung jawab bersama terhadap pengalaman pengguna. Jika integrasi kurang optimal, pengalaman pengguna akan terkena dampak negatif.

Salah satu penyebab performa buruk yang telah diketahui adalah penggunaan document.write() di dalam halaman, khususnya yang menggunakan skrip injeksi. Meskipun terlihat tidak berbahaya, aplikasi ini dapat menimbulkan masalah yang nyata bagi pengguna.

document.write('<script src="https://example.com/ad-inject.js"></script>');

Sebelum dapat merender halaman, browser harus membangun hierarki DOM dengan menguraikan markup HTML. Setiap kali parser menemukan skrip, parser harus menghentikan dan mengeksekusinya agar dapat melanjutkan menguraikan HTML. Jika skrip memasukkan skrip lain secara dinamis, parser akan dipaksa untuk menunggu bahkan lebih lama untuk mengunduh sumber daya, yang dapat menimbulkan satu atau lebih perjalanan bolak-balik jaringan dan menunda waktu hingga render pertama halaman

Untuk pengguna dengan koneksi lambat, seperti 2G, skrip eksternal secara dinamis yang dimasukkan melalui document.write() dapat menunda tampilan konten halaman utama untuk puluhan detik, atau menyebabkan laman gagal dimuat atau memakan waktu pengguna menyerah. Berdasarkan instrumentasi di Chrome, kami telah mempelajari bahwa halaman yang menampilkan skrip pihak ketiga yang disisipkan melalui document.write() yang biasanya dua kali lebih lambat untuk dimuat dibandingkan halaman lain di 2G.

Kami mengumpulkan data dari uji coba lapangan selama 28 hari di 1% aplikasi Chrome pengguna stabil, terbatas untuk pengguna dengan koneksi 2G. Kami melihat bahwa 7,6% dari semua pemuatan halaman pada 2G menyertakan setidaknya satu skrip lintas situs yang memblokir parser disisipkan melalui document.write() dalam dokumen tingkat atas. Akibat pemblokiran pemuatan skrip ini, kami melihat peningkatan berikut pada pemuatannya:

  • 10% lebih banyak pemuatan halaman mencapai first contentful paint (konfirmasi visual untuk pengguna bahwa halaman dimuat secara efektif), 25% lebih banyak pemuatan halaman yang mencapai status diuraikan sepenuhnya, dan 10% lebih sedikit pemuatan ulang menunjukkan penurunan rasa frustrasi pengguna.
  • 21% penurunan waktu rata-rata (lebih cepat satu detik) sampai first contentful paint
  • 38% pengurangan waktu rata-rata yang diperlukan untuk mengurai halaman, yang mewakili peningkatan hampir enam detik, yang secara dramatis mengurangi waktu yang diperlukan untuk menampilkan apa yang penting bagi pengguna.

Dengan mempertimbangkan data ini, Chrome, mulai versi 55, intervensi atas nama semua saat kami mendeteksi pola yang diketahui buruk ini dengan mengubah cara document.write() ditangani di Chrome (Lihat Status Chrome). Secara khusus, Chrome tidak akan mengeksekusi elemen <script> yang dimasukkan melalui document.write() saat semua kondisi berikut terpenuhi:

  1. Pengguna menggunakan koneksi yang lambat, khususnya saat pengguna menggunakan 2G. (Di di masa depan, perubahan itu mungkin meluas ke pengguna lain dengan koneksi lambat, seperti 3G yang lambat atau WiFi lambat.)
  2. document.write() berada dalam dokumen tingkat atas. Intervensi ini tidak berlaku untuk skrip document.write dalam iframe karena tidak memblokir {i>rendering<i} untuk laman utama.
  3. Skrip di document.write() memblokir parser. Skrip dengan 'async' atau 'defer' atribut akan tetap dieksekusi.
  4. Skrip tidak dihosting di situs yang sama. Dengan kata lain, Chrome akan tidak mengintervensi skrip dengan eTLD+1 yang cocok (misalnya skrip yang dihosting di js.example.org disisipkan di www.example.org).
  5. Skrip belum ada di cache HTTP browser. Skrip dalam cache tidak akan mengalami penundaan jaringan dan akan tetap dijalankan.
  6. Permintaan untuk halaman tersebut bukan pemuatan ulang. Chrome tidak akan ikut campur jika memicu muat ulang dan akan mengeksekusi halaman seperti biasa.

Cuplikan pihak ketiga terkadang menggunakan document.write() untuk memuat skrip. Untungnya, sebagian besar pihak ketiga menyediakan alternatif pemuatan asinkron, yang memungkinkan skrip pihak ketiga untuk dimuat tanpa memblokir tampilan konten pada halaman.

Bagaimana cara mengatasinya?

Jawaban sederhana ini adalah jangan memasukkan skrip menggunakan document.write(). Rab mempertahankan kumpulan layanan yang dikenal untuk dukungan loader asinkron sebaiknya Anda terus memeriksanya.

Jika penyedia Anda tidak ada dalam daftar dan mendukung pemuatan skrip asinkron selanjutnya, harap beri tahu kami dan kami dapat memperbarui halaman ini untuk membantu semua pengguna.

Jika penyedia Anda tidak mendukung kemampuan untuk memuat skrip secara asinkron ke halaman Anda, maka sebaiknya hubungi mereka dan beri tahu kami dan mereka bagaimana mereka akan terdampak.

Jika penyedia Anda memberi Anda cuplikan yang menyertakan document.write(), maka Anda mungkin dapat menambahkan atribut async ke elemen skrip, atau agar Anda dapat menambahkan elemen skrip dengan DOM API seperti document.appendChild() atau parentNode.insertBefore().

Cara mendeteksi kapan situs Anda terpengaruh

Ada banyak kriteria yang menentukan apakah pembatasan itu ditegakkan, jadi bagaimana cara mengetahui apakah Anda terpengaruh?

Mendeteksi saat pengguna menggunakan jaringan 2G

Untuk memahami potensi dampak perubahan ini, Anda harus lebih memahami berapa banyak pengguna Anda yang akan menggunakan 2G. Anda dapat mendeteksi jenis jaringan pengguna saat ini yang cepat menggunakan Network Information API yang tersedia di Chrome, lalu mengirimkan pemberitahuan ke Metrik Pengguna Sebenar atau analisis Anda (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.
}

Peringatan umum di Chrome DevTools

Mulai Chrome 53, DevTools mengeluarkan peringatan untuk document.write() yang bermasalah pernyataan pribadi Anda. Khususnya, jika permintaan document.write() memenuhi kriteria 2 hingga 5 (Chrome mengabaikan kriteria koneksi saat mengirim peringatan ini), peringatan akan kurang lebih akan terlihat seperti ini:

Peringatan penulisan dokumen.

Melihat peringatan di Chrome DevTools bagus, tetapi bagaimana Anda mendeteksinya di skala perusahaan? Anda dapat memeriksa header HTTP yang dikirim ke server Anda saat intervensi akan terjadi.

Periksa header HTTP Anda di resource skrip

Apabila skrip yang disisipkan melalui document.write telah diblokir, Chrome akan mengirim header berikut ke resource yang diminta:

Intervention: <https://shorturl/relevant/spec>;

Saat skrip yang disisipkan melalui document.write ditemukan dan dapat diblokir di keadaan yang berbeda, Chrome mungkin mengirim:

Intervention: <https://shorturl/relevant/spec>; level="warning"

Header intervensi akan dikirim sebagai bagian dari permintaan GET untuk skrip (secara asinkron jika terjadi intervensi sebenarnya).

Apa yang ada di masa depan?

Rencana awalnya adalah menjalankan intervensi ini ketika kami mendeteksi kriteria terpenuhi. Kami mulai dengan hanya menampilkan peringatan di Konsol Developer pada Chrome 53. (Beta pada Juli 2016. Kami berharap Stabil tersedia untuk semua pengguna di September 2016.)

Kami akan melakukan intervensi untuk memblokir skrip yang diinjeksikan untuk pengguna 2G untuk sementara yang dimulai pada Chrome 54, yang diperkirakan rilis stabil untuk semua pengguna di pertengahan Oktober 2016. Lihat Entri Status Chrome untuk mengetahui info terbaru lainnya.

Seiring waktu, kami ingin mengintervensi saat setiap pengguna memiliki koneksi yang lambat (yaitu, lambat pada 3G atau WiFi). Ikuti entri Status Chrome ini.

Ingin mempelajari lebih lanjut?

Untuk mempelajari lebih lanjut, lihat referensi tambahan berikut: