เมื่อเร็วๆ นี้คุณเห็นคำเตือนต่อไปนี้ในคอนโซลนักพัฒนาซอฟต์แวร์ใน 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()
อาจทำให้การแสดงเนื้อหาหลักของหน้าช้าลงหลาย 10 วินาที หรือทำให้หน้าเว็บโหลดไม่ได้หรือใช้เวลานานเกินไปจนผู้ใช้หมดความอดทน จากเครื่องมือวัดใน Chrome เราพบว่าหน้าเว็บที่มีสคริปต์ของบุคคลที่สามที่แทรกผ่าน document.write()
มักจะโหลดช้ากว่าหน้าอื่นๆ 2 เท่าในเครือข่าย 2G
เรารวบรวมข้อมูลจากการทดสอบภาคสนาม 28 วันในผู้ใช้ Chrome 1% ที่ใช้เวอร์ชันเสถียร ซึ่งจำกัดไว้สำหรับผู้ใช้ที่มีการเชื่อมต่อ 2G เท่านั้น เราพบว่าการโหลดหน้าเว็บทั้งหมด 7.6% ใน 2G ใช้สคริปต์การบล็อกโปรแกรมวิเคราะห์ข้ามเว็บไซต์อย่างน้อย 1 รายการที่แทรกผ่าน document.write()
ในเอกสารระดับบนสุด ผลจากการบล็อกการโหลดสคริปต์เหล่านี้ เราพบว่าการโหลดเหล่านั้นได้รับการปรับปรุงดังต่อไปนี้
- การโหลดหน้าเว็บที่ไปถึงFirst Contentful Paint (การยืนยันด้วยภาพว่าหน้าเว็บโหลดได้อย่างมีประสิทธิภาพ) เพิ่มขึ้น10% การโหลดหน้าเว็บที่ไปถึงสถานะแยกวิเคราะห์อย่างสมบูรณ์เพิ่มขึ้น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.written ภายใน 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 จากนั้นส่งการแจ้งเตือนไปยังระบบข้อมูลวิเคราะห์หรือเมตริกผู้ใช้จริง (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 สําหรับสคริปต์ (แบบไม่สอดคล้องกันในกรณีที่มีการแทรกแซงจริง)
มีอะไรรอเราอยู่บ้างในอนาคต
แผนเริ่มต้นคือการดําเนินการแทรกแซงนี้เมื่อเราตรวจพบว่ามีคุณสมบัติตรงตามเกณฑ์ เราเริ่มด้วยการแสดงคำเตือนในคอนโซลของนักพัฒนาซอฟต์แวร์ใน Chrome 53 (เวอร์ชันเบต้าเปิดตัวเมื่อเดือนกรกฎาคม 2016 เราคาดว่าเวอร์ชันเสถียรจะพร้อมให้บริการแก่ผู้ใช้ทุกคนในเดือนกันยายน 2016)
เราจะแทรกแซงเพื่อบล็อกสคริปต์ที่แทรกสําหรับผู้ใช้ 2G โดยประมาณตั้งแต่ Chrome 54 ซึ่งคาดว่าจะอยู่ในรุ่นที่เสถียรสําหรับผู้ใช้ทุกคนในช่วงกลางเดือนตุลาคม 2016 ดูข้อมูลอัปเดตเพิ่มเติมได้ในรายการสถานะ Chrome
ในอนาคต เราต้องการแทรกแซงเมื่อผู้ใช้มีการเชื่อมต่อที่ช้า (เช่น 3G หรือ Wi-Fi ที่ช้า) ทำตามรายการสถานะ Chrome นี้
หากต้องการดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมได้จากแหล่งข้อมูลเพิ่มเติมเหล่านี้