ฉันคิดว่า Jake Archibald นำเสนอข้อมูลเชิงลึกบางอย่างให้กับเราในปี 2013 ซึ่งอาจเพิ่มความเป็นบวกให้กับหัวข้อ:
https://www.html5rocks.com/en/tutorials/speed/script-loading/
จอกศักดิ์สิทธิ์กำลังมีชุดของสคริปต์ที่ดาวน์โหลดทันทีโดยไม่ปิดกั้นการเรนเดอร์และดำเนินการโดยเร็วที่สุดตามลำดับที่เพิ่มเข้ามา น่าเสียดายที่ HTML เกลียดคุณและจะไม่ยอมให้คุณทำเช่นนั้น
( ... )
คำตอบนั้นอยู่ในข้อมูลจำเพาะของ HTML5 แม้ว่าจะซ่อนอยู่ที่ด้านล่างของส่วนการโหลดสคริปต์ " แอตทริบิวต์ async IDL ควบคุมว่าองค์ประกอบจะดำเนินการแบบอะซิงโครนัสหรือไม่หากตั้งค่าสถานะ" force-async "ขององค์ประกอบจากนั้นเมื่อได้รับแอตทริบิวต์ async IDL ต้องส่งคืนค่าจริงและตั้งค่า" force-async " การตั้งค่าสถานะต้องยกเลิกการตั้งค่าก่อน ... "
( ... )
สคริปต์ที่สร้างขึ้นและเพิ่มลงในเอกสารเป็นแบบไดนามิกโดยค่าเริ่มต้นสคริปต์จะไม่บล็อกการแสดงผลและดำเนินการทันทีที่ดาวน์โหลดหมายความว่าอาจออกมาผิดลำดับ อย่างไรก็ตามเราสามารถทำเครื่องหมายอย่างชัดเจนว่าไม่ใช่ async:
[
'//other-domain.com/1.js',
'2.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
สิ่งนี้ทำให้สคริปต์ของเรามีพฤติกรรมที่ไม่สามารถทำได้ด้วย HTML ธรรมดา โดยไม่ชัดเจนอะซิงก์จะถูกเพิ่มสคริปต์ในคิวการดำเนินการคิวเดียวกันกับที่เพิ่มในตัวอย่างธรรมดา HTML แรกของเรา อย่างไรก็ตามโดยการสร้างแบบไดนามิกพวกเขาจะถูกดำเนินการนอกเหนือจากการแยกเอกสารเพื่อให้การแสดงผลไม่ถูกบล็อกในขณะที่พวกเขากำลังดาวน์โหลด
สคริปต์ด้านบนควรรวมอยู่ในส่วนหัวของหน้าจัดลำดับการดาวน์โหลดสคริปต์โดยเร็วที่สุดโดยไม่รบกวนการแสดงผลแบบก้าวหน้าและดำเนินการโดยเร็วที่สุดเท่าที่จะทำได้ตามลำดับที่คุณระบุ “ 2.js” นั้นสามารถดาวน์โหลดได้ฟรีก่อน“ 1.js” แต่มันจะไม่ถูกดำเนินการจนกว่า“ 1.js” จะดาวน์โหลดและดำเนินการสำเร็จหรือไม่สามารถทำได้ เย่! ดาวน์โหลด async แต่สั่งดำเนินการ !
ถึงกระนั้นนี่อาจไม่ใช่วิธีที่เร็วที่สุดในการโหลดสคริปต์:
(... ) ด้วยตัวอย่างด้านบนเบราว์เซอร์จะต้องแยกวิเคราะห์และรันสคริปต์เพื่อค้นหาสคริปต์ที่จะดาวน์โหลด นี่จะซ่อนสคริปต์ของคุณจากสแกนเนอร์ที่โหลดไว้ล่วงหน้า เบราว์เซอร์ใช้สแกนเนอร์เหล่านี้เพื่อค้นหาแหล่งข้อมูลบนหน้าเว็บที่คุณน่าจะเข้าชมต่อไปหรือค้นพบแหล่งข้อมูลหน้าขณะที่ตัวแยกวิเคราะห์ถูกบล็อกโดยทรัพยากรอื่น
เราสามารถเพิ่มการค้นพบกลับมาได้โดยใส่ไว้ในส่วนหัวของเอกสาร:
<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">
สิ่งนี้จะบอกเบราว์เซอร์ว่าหน้าต้องการ 1.js และ 2.js link [rel = subresource] นั้นคล้ายคลึงกับ link [rel = prefetch] แต่มีความหมายต่างกัน น่าเสียดายที่ขณะนี้รองรับ Chrome เท่านั้นและคุณต้องประกาศว่าสคริปต์ใดที่ต้องโหลดสองครั้งครั้งผ่านองค์ประกอบลิงก์และอีกครั้งในสคริปต์ของคุณ
การแก้ไข: ในขั้นต้นฉันระบุว่าสิ่งเหล่านี้ถูกสแกนเนอร์แบบพรีเพด แต่ไม่ใช่พวกเขาจะถูกเลือกโดย parser ปกติ อย่างไรก็ตามสแกนเนอร์ที่โหลดล่วงหน้าสามารถเลือกสิ่งเหล่านี้ได้ แต่มันก็ยังไม่เกิดขึ้นในขณะที่สคริปต์ที่รวมอยู่ในโค้ดที่รันได้จะไม่สามารถโหลดล่วงหน้าได้ ขอบคุณ Yoav ไวส์ที่แก้ไขฉันในความคิดเห็น
async
ใหม่ (ish) แต่defer
เป็นส่วนหนึ่งของ IE มาตั้งแต่ IE4defer
ถูกเพิ่มไปยังเบราว์เซอร์อื่น ๆ มากขึ้นเมื่อเร็ว ๆ นี้ แต่เบราว์เซอร์ที่เก่ากว่านั้นมักจะแฮงค์น้อยกว่ามาก