เมื่อเร็วๆ นี้คุณเห็นคำเตือนที่มีลักษณะดังต่อไปนี้ใน Developer Console ใน Chrome หรือไม่ และสงสัยว่าข้อความนี้คืออะไร
(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.
ความสามารถในการประกอบเป็นหนึ่งในพลังที่ยอดเยี่ยมของเว็บ ซึ่งช่วยให้เราผสานรวมบริการที่สร้างโดยบุคคลที่สามเพื่อสร้างผลิตภัณฑ์ใหม่ๆ ที่ยอดเยี่ยมได้อย่างง่ายดาย ข้อเสียอย่างหนึ่งของความสามารถในการเขียนก็คือการกล่าวเป็นนัยถึงความรับผิดชอบร่วมกันที่มีต่อประสบการณ์ของผู้ใช้ หากการผสานรวมมีประสิทธิภาพไม่ดีนัก ประสบการณ์ของผู้ใช้จะได้รับผลกระทบเชิงลบ
หนึ่งในสาเหตุที่ทราบว่าให้ประสิทธิภาพไม่ดีคือการใช้ document.write()
ภายในหน้าเว็บ โดยเฉพาะที่ใช้การแทรกสคริปต์ ดังที่เห็นแล้วไม่น่าเป็นห่วง
อาจสร้างปัญหาที่แท้จริงให้กับผู้ใช้ได้
document.write('<script src="https://example.com/ad-inject.js"></script>');
ก่อนที่เบราว์เซอร์จะแสดงผลหน้าเว็บได้ เบราว์เซอร์จะต้องสร้างแผนผัง DOM โดยการแยกวิเคราะห์มาร์กอัป HTML เมื่อใดก็ตามที่โปรแกรมแยกวิเคราะห์พบสคริปต์ โปรแกรมแยกวิเคราะห์จะต้องหยุดและดำเนินการ จึงจะแยกวิเคราะห์ HTML ต่อไปได้ หากสคริปต์แทรกสคริปต์อื่นแบบไดนามิก โปรแกรมแยกวิเคราะห์จะบังคับให้รอดาวน์โหลดทรัพยากรนานขึ้น ซึ่งอาจทําให้เกิดการรับส่งข้อมูลไปกลับของเครือข่ายอย่างน้อย 1 ครั้ง และทำให้เกิดความล่าช้าในการแสดงผลหน้าเว็บครั้งแรก
สำหรับผู้ใช้ที่มีการเชื่อมต่อที่ช้า เช่น 2G สคริปต์ภายนอกที่แทรกเข้ามาแบบไดนามิกผ่าน document.write()
อาจหน่วงเวลาการแสดงเนื้อหาหลักของหน้าไปหลายสิบวินาที หรือทำให้หน้าเว็บโหลดไม่สำเร็จหรือใช้เวลานานเกินไปจนผู้ใช้ปิดไป จากการใช้เครื่องมือใน Chrome เราได้เรียนรู้ว่าหน้าเว็บที่มีสคริปต์ของบุคคลที่สามที่แทรกผ่าน document.write()
มักจะโหลดได้ช้ากว่าหน้าอื่นๆ ในเครือข่าย 2G ถึง 2 เท่า
เราเก็บรวบรวมข้อมูลจากช่วงทดลองใช้งานภาคสนาม 28 วันกับผู้ใช้ Chrome เวอร์ชันเสถียร 1% โดยจำกัดไว้เฉพาะผู้ใช้ที่ใช้การเชื่อมต่อ 2G เราพบว่า 7.6% ของการโหลดหน้าเว็บทั้งหมดบน 2G มีสคริปต์บล็อกโปรแกรมแยกวิเคราะห์แบบข้ามเว็บไซต์อย่างน้อย 1 รายการที่แทรกผ่าน document.write()
ในเอกสารระดับบนสุด การบล็อกการโหลดสคริปต์เหล่านี้ทำให้เราเห็นการปรับปรุงดังต่อไปนี้ในการโหลดสคริปต์ดังกล่าว
- การโหลดหน้าเว็บเพิ่มขึ้น 10% ที่ถึง First Contentful Paint (ภาพยืนยันสำหรับผู้ใช้ว่าหน้าเว็บกำลังโหลดอย่างมีประสิทธิภาพ) มีการโหลดหน้าเว็บมากขึ้น 25% ที่ถึงสถานะการแยกวิเคราะห์อย่างสมบูรณ์ และการโหลดซ้ำน้อยลง 10% ทำให้ผู้ใช้รู้สึกหงุดหงิดน้อยลง
- เวลาเฉลี่ยลดลง 21% (เร็วกว่า 1 วินาที) จนถึง First Contentful Paint
- ลดเวลาเฉลี่ยในการแยกวิเคราะห์หน้าเว็บลง 38% ซึ่งเพิ่มขึ้นเกือบ 6 วินาที ซึ่งช่วยประหยัดเวลาในการแสดงสิ่งที่สำคัญต่อผู้ใช้ได้อย่างมาก
เมื่อคำนึงถึงข้อมูลนี้ Chrome ซึ่งเริ่มตั้งแต่เวอร์ชัน 55 จะแทรกแซงในนามของผู้ใช้ทั้งหมดเมื่อเราตรวจพบรูปแบบที่ไม่ดีซึ่งเป็นที่รู้จักนี้โดยเปลี่ยนวิธีจัดการ document.write()
ใน Chrome (ดูสถานะของ Chrome)
กล่าวโดยละเอียดคือ Chrome จะไม่เรียกใช้เอลิเมนต์ <script>
ที่แทรกผ่าน document.write()
เมื่อเป็นไปตามเงื่อนไขทั้งหมดต่อไปนี้
- ผู้ใช้อยู่ในการเชื่อมต่อที่ช้า โดยเฉพาะเมื่อผู้ใช้ใช้ 2G (ในอนาคต การเปลี่ยนแปลงอาจมีผลกับผู้ใช้คนอื่นๆ ที่การเชื่อมต่อช้า เช่น 3G หรือ Wi-Fi ช้า)
document.write()
อยู่ในเอกสารระดับบนสุด การฝึกฝนนี้ไม่ใช้กับสคริปต์ document.write ภายใน iframe เนื่องจากไม่ได้บล็อกการแสดงหน้าหลัก- สคริปต์ใน
document.write()
กำลังบล็อกโปรแกรมแยกวิเคราะห์ สคริปต์ที่มีแอตทริบิวต์ "async
" หรือ "defer
" จะยังคงดำเนินการอยู่ - สคริปต์ไม่ได้โฮสต์อยู่ในเว็บไซต์เดียวกัน กล่าวคือ Chrome จะไม่แทรกแซงสคริปต์ที่มี eTLD+1 ที่ตรงกัน (เช่น สคริปต์ที่โฮสต์ใน js.example.org ซึ่งแทรกไว้ใน www.example.org)
- สคริปต์ไม่ได้อยู่ในแคช HTTP ของเบราว์เซอร์แล้ว สคริปต์ในแคชจะไม่ก่อให้เกิดความล่าช้าของเครือข่ายและจะยังคงดำเนินการอยู่
- คำขอสำหรับหน้านี้ไม่ใช่การโหลดซ้ำ Chrome จะไม่เข้าไปแทรกแซงถ้าผู้ใช้ทริกเกอร์การโหลดซ้ำและจะทำงานตามปกติ
บางครั้งข้อมูลโค้ดของบุคคลที่สามจะใช้ document.write()
เพื่อโหลดสคริปต์
โชคดีที่บุคคลที่สามส่วนใหญ่มีทางเลือกในการโหลดแบบอะซิงโครนัส ซึ่งช่วยให้สคริปต์ของบุคคลที่สามโหลดได้โดยไม่บล็อกการแสดงเนื้อหาที่เหลือในหน้า
ฉันจะแก้ไขปัญหานี้ได้อย่างไร
คำตอบง่ายๆ นี้คือไม่แทรกสคริปต์โดยใช้ document.write()
เราดูแลรักษาชุดบริการที่รู้จักสำหรับการรองรับตัวโหลดแบบไม่พร้อมกันที่เราขอแนะนำให้คุณตรวจสอบต่อไป
หากผู้ให้บริการของคุณไม่อยู่ในรายการดังกล่าวและรองรับการโหลดสคริปต์แบบไม่พร้อมกัน โปรดแจ้งให้เราทราบ แล้วเราจะได้อัปเดตหน้านี้เพื่อช่วยเหลือผู้ใช้ทุกคน
หากผู้ให้บริการไม่รองรับความสามารถในการโหลดสคริปต์แบบไม่พร้อมกันลงในหน้าเว็บ เราขอแนะนำให้คุณติดต่อผู้ให้บริการและแจ้งให้เราทราบว่าสคริปต์จะได้รับผลกระทบอย่างไร
หากผู้ให้บริการให้ข้อมูลโค้ดที่มี document.write()
แก่คุณ คุณก็อาจเพิ่มแอตทริบิวต์ async
ลงในองค์ประกอบสคริปต์ หรือเพิ่มองค์ประกอบสคริปต์ที่มี DOM API เช่น document.appendChild()
หรือ parentNode.insertBefore()
ได้
วิธีตรวจหาเมื่อเว็บไซต์ของคุณได้รับผลกระทบ
มีเกณฑ์จำนวนมากที่ใช้พิจารณาว่ามีข้อจำกัดหรือไม่ แล้วคุณจะรู้ได้อย่างไรว่าได้รับผลกระทบหรือไม่
ตรวจจับเมื่อผู้ใช้ใช้งาน 2G
เพื่อทำความเข้าใจผลกระทบที่อาจเกิดขึ้นของการเปลี่ยนแปลงนี้ ก่อนอื่นคุณต้องเข้าใจจำนวนผู้ใช้ที่จะใช้ 2G คุณตรวจหาประเภทและความเร็วเครือข่ายปัจจุบันของผู้ใช้ได้โดยใช้ Network Information API ที่มีให้ใช้งานใน Chrome จากนั้นส่งคำเตือนไปยังระบบ Analytic หรือระบบเมตริกผู้ใช้จริง (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.
}
ตรวจจับคำเตือนในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
ตั้งแต่ Chrome 53 เครื่องมือสำหรับนักพัฒนาเว็บจะออกคำเตือนสำหรับคำสั่ง document.write()
ที่เป็นปัญหา โดยเฉพาะอย่างยิ่ง หากคำขอ document.write()
ตรงตามเกณฑ์ 2 ถึง 5 (Chrome จะไม่สนใจเกณฑ์การเชื่อมต่อเมื่อส่งคำเตือนนี้) คำเตือนจะมีลักษณะดังนี้
การเห็นคำเตือนในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เป็นเรื่องดี แต่คุณจะตรวจพบคำเตือนในวงกว้างได้อย่างไร คุณสามารถตรวจสอบส่วนหัว HTTP ที่ส่งไปยังเซิร์ฟเวอร์ของคุณเมื่อมีการแทรกแซงเกิดขึ้นได้
ตรวจสอบส่วนหัว HTTP ในทรัพยากรของสคริปต์
เมื่อสคริปต์ที่แทรกผ่าน document.write
ถูกบล็อก Chrome จะส่งส่วนหัวต่อไปนี้ไปยังทรัพยากรที่ขอ
Intervention: <https://shorturl/relevant/spec>;
เมื่อพบสคริปต์ที่แทรกผ่าน document.write
และอาจถูกบล็อกในสถานการณ์ที่ต่างกัน Chrome อาจส่งรายการต่อไปนี้
Intervention: <https://shorturl/relevant/spec>; level="warning"
ระบบจะส่งส่วนหัวการฝึกฝนเป็นส่วนหนึ่งของคำขอ GET สำหรับสคริปต์ (ไม่พร้อมกันในกรณีที่มีการดำเนินการจริง)
มีอะไรรอเราอยู่บ้างในอนาคต
แผนเริ่มต้นคือการฝึกฝนนี้เมื่อตรวจพบว่ามีคุณสมบัติตรงตามเกณฑ์ เราเริ่มจากการแสดงเพียงคำเตือนใน Developer Console ใน Chrome 53 (รุ่นเบต้าอยู่ในเดือนกรกฎาคม 2016 เราคาดว่าเวอร์ชันเสถียรจะพร้อมใช้งานสำหรับผู้ใช้ทุกคนในเดือนกันยายน 2016)
เราจะเข้าไปบล็อกสคริปต์ที่แทรกไว้สำหรับผู้ใช้ 2G ในเบื้องต้นใน Chrome 54 ซึ่งคาดว่าจะเป็นเวอร์ชันเสถียรสำหรับผู้ใช้ทุกคนในช่วงกลางเดือนตุลาคม 2016 ดูรายการสถานะ Chrome สำหรับการอัปเดตเพิ่มเติม
เมื่อเวลาผ่านไป เราต้องการที่จะเข้ามาแทรกแซงในกรณีที่การเชื่อมต่อของผู้ใช้ช้า (เช่น 3G หรือ Wi-Fi ที่ช้า) ทำตามรายการสถานะของ Chrome
หากต้องการข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมได้จากแหล่งข้อมูลต่อไปนี้