โหลดข้อความ javascript async src แล้ว การโหลด JavaScript แบบอะซิงโครนัส - เพิ่มความเร็วในการโหลดหน้าเว็บ การโหลดสคริปต์ HTML5 แบบอะซิงโครนัส
มีวิธีแก้ไข: ใส่สตริง Java ที่ส่วนท้าย เอกสาร html(ดังนั้นจะโหลดหลังจากวาดทั้งหน้าแล้ว) และหลังจากนั้นเนื้อหาของบล็อกจะแสดงในตำแหน่งที่ถูกต้องเท่านั้น มันเรียกว่า. โครงการที่จริงจังทั้งหมดในปัจจุบันกำลังพยายามเปลี่ยนไปใช้ เทคโนโลยีใหม่ดาวน์โหลด นอกจากนี้มันเป็นเรื่องง่ายอย่างแน่นอน
มีหลายวิธี ฉันจะเริ่มตามลำดับ
script src= type= "text/javascript">
การโหลดสคริปต์ HTML5 แบบอะซิงโครนัสมาตรฐาน HTML5 รองรับความสามารถในการโหลดสคริปต์แบบอะซิงโครนัส ซึ่งสามารถเร่งความเร็วในการดึงข้อมูลเพจโดยรวมได้อย่างมาก เพียงเพิ่ม async หรือ defer
< script async src= "http://www.site.ru/script.js" type= "text/javascript" >
< script defer src= "http://www.site.ru/script.js" type= "text/javascript" >
ความแตกต่างระหว่างแอตทริบิวต์ async และ defer คืออะไร?
ในทั้งสองกรณีเราได้รับการโหลดสคริปต์แบบอะซิงโครนัส ข้อแตกต่างเพียงอย่างเดียวคือช่วงเวลาที่สคริปต์เริ่มทำงาน สคริปต์ที่มีแอตทริบิวต์ async จะถูกดำเนินการโดยเร็วที่สุดหลังจากที่โหลดจนเต็ม แต่ก่อนที่จะโหลดวัตถุหน้าต่าง หากใช้แอตทริบิวต์ defer สคริปต์จะไม่ละเมิดลำดับการดำเนินการที่เกี่ยวข้องกับสคริปต์อื่นๆ และการดำเนินการจะเกิดขึ้นหลังจากที่เพจโหลดและแยกวิเคราะห์อย่างสมบูรณ์ แต่ก่อนเหตุการณ์ DOMContentLoaded ของออบเจ็กต์เอกสาร
ขออภัย กลไกนี้ใช้ไม่ได้กับบางเบราว์เซอร์ในปัจจุบัน (โดยเฉพาะ IE) นอกจากนี้ยังจะไม่ทำงานหากมีบรรทัด document.write ในไฟล์ script.js
การโหลดจาวาสคริปต์แบบอะซิงโครนัสด้วยสคริปต์ของ Googleดังที่ผู้เชี่ยวชาญทุกคนรู้ดีว่า Google เป็นผู้จ่ายเงิน ความสนใจเป็นพิเศษความเร็วในการโหลดเว็บไซต์ และลดความเร็วที่ช้าในผลการค้นหา เพื่อช่วย Google ได้พัฒนาสคริปต์พิเศษซึ่งคุณสามารถโหลดจาวาสคริปต์แบบอะซิงโครนัสได้
หากต้องการใช้เพียงแค่เปลี่ยน
บน
และเชื่อมต่อไฟล์สคริปต์ extsrc.js
มันจะออกมาดังนี้:
< script src= "http://extsrcjs.googlecode.com/svn/trunk/extsrc.js" > < script extsrc= "...." >
น่าเสียดายที่วิธีนี้ใช้ไม่ได้กับไฟล์ที่มี document.write
การโหลดจาวาสคริปต์แบบอะซิงโครนัสที่ทำงานได้ดีที่สุดวิธีการสากลสำหรับเบราว์เซอร์ทั้งหมด ใช้งานได้กับ document.write
ในตำแหน่งบนหน้าที่เราต้องการแสดงองค์ประกอบของเรา ให้สร้างบล็อก div ว่าง:
< div id= "script_block" class = "script_block" >
ที่ส่วนท้ายสุดของหน้า ก่อนที่เราจะแทรกสคริปต์สำหรับการโหลดไฟล์แบบอะซิงโครนัส:
< div id= "script_ad" class = "script_ad" style= "display:none;" >นี่คือไฟล์หรือสคริปต์ใดๆ ที่ต้องโหลด< script type= "text/javascript" >// ย้ายไปยังเอกสารตำแหน่งที่แสดงจริง getElementById("script_block" ) . appendChild(document.getElementById("script_ad" ) ) ;
//แสดงเอกสาร. getElementById("script_ad") . สไตล์. จอแสดงผล = "บล็อก" ;
ใน IE เวอร์ชันเก่าที่สุด (6 และต่ำกว่า) การโหลดแบบอะซิงโครนัสใช้งานไม่ได้ แต่ในทางปฏิบัติแล้วไม่มีผู้ใช้ดังกล่าวอีกต่อไป เบราว์เซอร์และบริการอื่น ๆ ทั้งหมดใช้การโหลดหน้าเว็บแบบเร่งความเร็วสมัยใหม่ได้สำเร็จ
สวัสดีเพื่อนๆ! คุณรู้หรือไม่ว่าการโหลด JavaScript เป็นหนึ่งในปัญหาคอขวดที่ใหญ่ที่สุดในประสิทธิภาพของเว็บไซต์ วันนี้งานหลักของฉันคือการอธิบายว่าสคริปต์คืออะไร และส่งผลต่อความเร็วและประสิทธิภาพของไซต์อย่างไร
- เบราว์เซอร์ที่โหลดแท็กสคริปต์จะหยุดแสดงผลเพจจนกว่าสคริปต์จะโหลดและดำเนินการ เพจถูกบล็อกและเบราว์เซอร์ไม่ตอบสนองต่อการกระทำของผู้ใช้เป็นเวลาสองสามวินาที เวลาล่าช้าขึ้นอยู่กับปัจจัยหลายประการ:
- การกำหนดค่า
- ความเร็วการเชื่อมต่ออินเทอร์เน็ต
ขนาดไฟล์และอื่นๆ...
ด้วยเหตุนี้ เครื่องมือวิเคราะห์ความเร็วเว็บไซต์ Google PageSpeed Insights จึงแนะนำให้ลบโค้ด JavaScript ที่บล็อกการแสดงผลที่ด้านบนของหน้า แนวปฏิบัติที่ดีคือการวางสคริปต์ไว้ที่ด้านล่างของไซต์ เช่น ก่อนแท็กปิด หรือตั้งค่าการโหลดแบบอะซิงโครนัส หากโค้ดสคริปต์ส่งผลต่อการแสดงส่วนบนของเว็บไซต์ อย่าวางไว้แยกไฟล์
และฝังโดยตรงใน HTML
JS สามารถเปลี่ยนเนื้อหาของไซต์และเปลี่ยนเส้นทางไปยัง URL อื่นได้ ในกรณีนี้ การเชื่อมต่อสคริปต์ที่ส่วนท้ายของเอกสารจะส่งผลให้เกิด "การกระตุก" หน้า การโหลดใหม่หรือการเปลี่ยนแปลงองค์ประกอบที่มีอยู่ที่ด้านบนการใช้แอตทริบิวต์ async และ defer กับแท็กสคริปต์
< src ="example.js" >เรามาดูกันว่างานแบบอะซิงโครนัสและแบบเลื่อนเวลาใน JavaScript คืออะไร และอะไรคือความแตกต่างพื้นฐานระหว่างแอตทริบิวต์ async และ defer แต่ก่อนอื่น เรามาดูลำดับการประมวลผลเอกสารโดยรวมแท็กสคริปต์ตามปกติ สำหรับตัวอย่างภาพ ฉันจะใช้สิ่งต่อไปนี้:
สัญลักษณ์
— การประมวลผลหน้า
— กำลังโหลดสคริปต์
— การดำเนินการสคริปต์
ดังนั้นลำดับการประมวลผลจึงเกิดขึ้นตามรูปแบบต่อไปนี้:
การแยกวิเคราะห์โค้ด HTML ถูกขัดจังหวะในขณะที่สคริปต์กำลังโหลดและดำเนินการ หลังจากนั้นสคริปต์จะดำเนินต่อไป มีความล่าช้าในการแสดงหน้าเว็บคุณลักษณะ defer ช่วยให้เบราว์เซอร์เริ่มดาวน์โหลดไฟล์ js แบบขนานโดยไม่หยุดการประมวลผลหน้าเว็บต่อไป การดำเนินการเกิดขึ้นหลังจากการแยกวิเคราะห์โมเดลออบเจ็กต์เอกสารอย่างสมบูรณ์ (จาก English Document Object Model หรือย่อว่า DOM) ในขณะที่เบราว์เซอร์รับประกันความสอดคล้องตามลำดับที่ไฟล์เชื่อมต่อกัน
< defer src ="example.js" >แอตทริบิวต์อะซิงโครนัสการสนับสนุนแอตทริบิวต์ async ที่ปรากฏใน HTML5 ช่วยให้เบราว์เซอร์ดาวน์โหลดไฟล์ js แบบขนานและดำเนินการได้ทันทีหลังจากดาวน์โหลด โดยไม่ต้องรอให้ส่วนที่เหลือของหน้าประมวลผล
< async src ="example.js" >แผนภาพลำดับการประมวลผล:
นี่คือการดาวน์โหลดแบบอะซิงโครนัส แนะนำให้ใช้แอตทริบิวต์นี้สำหรับใช้ในสคริปต์ที่ไม่มีผลกระทบอย่างมีนัยสำคัญต่อการแสดงเอกสาร ซึ่งรวมถึงตัวนับการเก็บสถิติ (Google Analytics, Yandex Metrica), รหัสเครือข่ายโฆษณา (Yandex Advertising Network, Google AdSense) ปุ่ม เครือข่ายทางสังคมและอื่น ๆ
ความเร็วในการโหลดเว็บไซต์เป็นหนึ่งในปัจจัยการจัดอันดับใน Google
การเชื่อมต่อ JavaScript แบบอะซิงโครนัสช่วยลดเวลาในการโหลดหน้าเว็บโดยกำจัดเวลาแฝง นอกจากนี้ ฉันขอแนะนำให้บีบอัดและรวมไฟล์ js ให้เป็นไฟล์เดียว เช่น การใช้นามสกุล . ผู้ใช้ชอบไซต์ที่รวดเร็ว 😎
องค์ประกอบ HTML ใช้เพื่อฝังหรืออ้างอิงโค้ดที่ปฏิบัติการได้ โดยทั่วไปจะใช้เพื่อฝังหรืออ้างอิงโค้ด JavaScript
หมวดหมู่เนื้อหา |
เนื้อหาที่ได้รับอนุญาต |
การละเว้นแท็ก |
ผู้ปกครองที่ได้รับอนุญาต |
บทบาท ARIA ที่ได้รับอนุญาต |
อินเตอร์เฟซโดม |
คุณสมบัติ async HTML5
สำหรับสคริปต์คลาสสิก หากมีแอตทริบิวต์ async สคริปต์คลาสสิกจะถูกดึงข้อมูลควบคู่ไปกับการแยกวิเคราะห์และประเมินทันทีที่พร้อมใช้งานองค์ประกอบสคริปต์ crossorigin Normal ส่งข้อมูลขั้นต่ำไปยัง window.onerror สำหรับสคริปต์ที่ไม่ผ่านการตรวจสอบ CORS มาตรฐาน หากต้องการอนุญาตการบันทึกข้อผิดพลาดสำหรับไซต์ที่ใช้โดเมนแยกต่างหากสำหรับสื่อคงที่ ให้ใช้แอตทริบิวต์นี้ ดูแอตทริบิวต์การตั้งค่า CORS สำหรับคำอธิบายที่ละเอียดยิ่งขึ้นเกี่ยวกับอาร์กิวเมนต์ที่ถูกต้อง
สคริปต์ที่มีแอตทริบิวต์ defer จะป้องกันไม่ให้เหตุการณ์ DOMContentLoaded เริ่มทำงานจนกว่าสคริปต์จะโหลดและประเมินเสร็จแล้ว
ต้องไม่ใช้แอตทริบิวต์นี้หากไม่มีแอตทริบิวต์ src (เช่น สำหรับสคริปต์อินไลน์) ในกรณีนี้จะไม่มีผลใดๆ
ตัวอย่างการใช้งานเบื้องต้นตัวอย่างเหล่านี้แสดงวิธีการนำเข้าสคริปต์ (ภายนอก) โดยใช้องค์ประกอบ
และตัวอย่างต่อไปนี้แสดงวิธีการใส่สคริปต์ (แบบอินไลน์) ภายในองค์ประกอบ
alert("สวัสดีชาวโลก!");
ทางเลือกโมดูลเบราว์เซอร์ที่รองรับค่าโมดูลสำหรับแอตทริบิวต์ type จะละเว้นสคริปต์ใด ๆ ที่มีแอตทริบิวต์ nomodule ซึ่งช่วยให้คุณสามารถใช้สคริปต์โมดูลในขณะเดียวกันก็จัดเตรียมสคริปต์สำรองที่ทำเครื่องหมาย nomodule สำหรับเบราว์เซอร์ที่ไม่รองรับ
ข้อมูลจำเพาะ
มาตรฐานการใช้ชีวิต HTML คำจำกัดความของ "" ในข้อกำหนดนั้น |
มาตรฐานการครองชีพ | ลบแอตทริบิวต์ชุดอักขระแล้ว |
HTML5 คำจำกัดความของ "" ในข้อกำหนดนั้น |
คำแนะนำ | |
ข้อมูลจำเพาะ HTML 4.01 คำจำกัดความของ "" ในข้อกำหนดนั้น |
คำแนะนำ |
ตารางความเข้ากันได้ในหน้านี้สร้างขึ้นจากข้อมูลที่มีโครงสร้าง หากคุณต้องการมีส่วนร่วมในข้อมูล โปรดตรวจสอบ https://github.com/mdn/browser-compat-data และส่งคำขอดึงถึงเรา
อัปเดตข้อมูลความเข้ากันได้บน GitHub
เดสก์ท็อปมือถือ | |||||||||||
โครม เอดจ์ ไฟร์ฟอกซ์ อินเทอร์เน็ตเอ็กซ์พลอเรอร์ Opera Safari Android webview Chrome สำหรับ Android Firefox สำหรับ Android Opera สำหรับ Android Safari บน iOS Samsung Internet | |||||||||||
การสนับสนุน Chrome เต็มรูปแบบ 1 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเต็มรูปแบบ 1 หมายเหตุ สนับสนุนอย่างเต็มที่1หมายเหตุ หมายเหตุ เริ่มต้นใน Firefox 4 การแทรกองค์ประกอบที่สร้างขึ้นโดยการเรียก document.createElement("script") จะไม่บังคับใช้การดำเนินการตามลำดับการแทรกอีกต่อไป การเปลี่ยนแปลงนี้ช่วยให้ Firefox ปฏิบัติตามข้อกำหนดได้อย่างถูกต้อง หากต้องการให้สคริปต์ภายนอกที่แทรกสคริปต์ดำเนินการตามลำดับการแทรก ให้ตั้งค่า .async=false บนสคริปต์เหล่านั้น | การสนับสนุน IE เต็มรูปแบบ ใช่ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | ||||||
การสนับสนุน Chrome เต็มรูปแบบ 1 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเต็มรูปแบบ 1 | การสนับสนุน IE เต็มรูปแบบ ใช่ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | รองรับ WebView Android เต็มรูปแบบ ใช่ | รองรับ Chrome Android เต็มรูปแบบใช่ | Firefox Android รองรับเต็มรูปแบบ 4 | รองรับ Opera Android เต็มรูปแบบ ใช่ | Safari iOS รองรับเต็มรูปแบบ ใช่ | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ |
Chrome รองรับเต็มรูปแบบ 30 | ขอบรองรับเต็ม ≤18 | Firefox รองรับเต็มรูปแบบ 13 | IE ไม่มีหมายเลขรองรับ | โอเปร่าสนับสนุนอย่างเต็มที่ 12 | รองรับ Safari เต็มรูปแบบ ใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ แอตทริบิวต์ crossorigin ถูกนำมาใช้ใน WebKit ใน WebKit bug 81438 | รองรับ WebView Android เต็มรูปแบบ ใช่ | รองรับ Chrome Android เต็มรูปแบบใช่ | Firefox Android รองรับเต็มรูปแบบ 14 | โอเปร่า แอนดรอยด์? | ซาฟารี iOS? | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ |
รองรับ Chrome เต็มรูปแบบ ใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ โครเมียม ฉบับที่ #611136 โครเมียม ฉบับที่ #874749 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเวอร์ชัน 3.5 เต็มรูปแบบ หมายเหตุ การสนับสนุนอย่างเต็มที่ 3.5หมายเหตุ หมายเหตุ ตั้งแต่ Firefox 3.6 แอตทริบิวต์ defer จะถูกละเว้นในสคริปต์ที่ไม่มีแอตทริบิวต์ src อย่างไรก็ตาม ใน Firefox 3.5 แม้แต่สคริปต์อินไลน์ก็ยังถูกเลื่อนออกไปหากมีการตั้งค่าแอตทริบิวต์ defer ไว้ | การสนับสนุน IE เต็มรูปแบบ 10 หมายเหตุ สนับสนุนอย่างเต็มที่ 10หมายเหตุ หมายเหตุ ในเวอร์ชันก่อน Internet Explorer 10 จะมีการใช้งานการเลื่อนตามข้อกำหนดเฉพาะที่เป็นกรรมสิทธิ์ ตั้งแต่เวอร์ชัน 10 เป็นต้นไป จะเป็นไปตามข้อกำหนด W3C | รองรับ Opera เต็มรูปแบบ ใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ โครเมียม ฉบับที่ #611136 โครเมียม ฉบับที่ #874749 | รองรับ Safari เต็มรูปแบบ ใช่ | รองรับ WebView Android เต็มรูปแบบ ใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ WebView ไม่เลื่อนสคริปต์ด้วยแอตทริบิวต์ defer เมื่อเพจทำหน้าที่เป็น XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749 | รองรับ Chrome Android เต็มรูปแบบใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ Chrome ไม่เลื่อนสคริปต์ด้วยแอตทริบิวต์ defer เมื่อหน้าเว็บแสดงเป็น XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749 | Firefox Android รองรับเต็มรูปแบบ 4 | รองรับ Opera Android เต็มรูปแบบ ใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ Opera ไม่เลื่อนสคริปต์ด้วยแอตทริบิวต์ defer เมื่อเพจทำหน้าที่เป็น XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749 | Safari iOS รองรับเต็มรูปแบบ ใช่ | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ หมายเหตุ สนับสนุนเต็มที่ครับหมายเหตุ หมายเหตุ Samsung Internet ไม่เลื่อนสคริปต์ด้วยแอตทริบิวต์ defer เมื่อเพจแสดงเป็น XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749 |
Chrome รองรับเต็มรูปแบบ 45 | การสนับสนุน Edge บางส่วน 17 | Firefox รองรับเต็มรูปแบบ 43 | IE ไม่มีหมายเลขรองรับ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | WebView Android รองรับเต็มรูปแบบ 45 | Chrome Android รองรับเต็มรูปแบบ 45 | Firefox Android รองรับเต็มรูปแบบ 43 | โอเปร่า แอนดรอยด์? | Safari iOS ไม่มีหมายเลขรองรับ | Samsung Internet Android รองรับเวอร์ชัน 5.0 เต็มรูปแบบ |
การสนับสนุน Chrome เต็มรูปแบบ 1 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเต็มรูปแบบ 1 | การสนับสนุน IE เต็มรูปแบบ ใช่ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | รองรับ WebView Android เต็มรูปแบบ ใช่ | รองรับ Chrome Android เต็มรูปแบบใช่ | Firefox Android รองรับเต็มรูปแบบ 4 | รองรับ Opera Android เต็มรูปแบบ ใช่ | Safari iOS รองรับเต็มรูปแบบ ใช่ | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ |
Chrome รองรับเต็มรูปแบบ 61 | รองรับ Edge เต็มรูปแบบ 16 | Firefox รองรับเต็มที่ 60 รองรับเต็มที่ 60 ไม่รองรับ 55 - 60 พิการ พิการ | IE ไม่มีหมายเลขรองรับ | โอเปร่าสนับสนุนอย่างเต็มที่ 48 | ซาฟารีรองรับเต็มรูปแบบ 11 | Firefox Android รองรับเต็มรูปแบบ 60 รองรับเต็มรูปแบบ 60 ไม่รองรับ 55 - 60 พิการ พิการ ตั้งแต่เวอร์ชัน 55 ถึงเวอร์ชัน 60 (เฉพาะ): คุณลักษณะนี้อยู่เบื้องหลังการตั้งค่า dom.moduleScripts.enabled (จำเป็นต้องตั้งค่าเป็นจริง) หากต้องการเปลี่ยนการตั้งค่าใน Firefox โปรดไปที่ about:config | Safari iOS รองรับเต็มรูปแบบ 11 | ||||
Chrome รองรับเต็มรูปแบบ 70 | ขอบรองรับเต็ม ≤79 | Firefox รองรับเต็มรูปแบบ 65 | IE ไม่มีหมายเลขรองรับ | รองรับ Opera เต็มรูปแบบ ใช่ | Safari ไม่มีหมายเลขรองรับ | รองรับ WebView Android เต็มรูปแบบ 70 | Chrome Android รองรับเต็มรูปแบบ 70 | Firefox Android รองรับเต็มรูปแบบ 65 | โอเปร่า แอนดรอยด์? | Safari iOS ไม่มีหมายเลขรองรับ | Samsung Internet Android รองรับเวอร์ชันเต็ม 10.0 |
การสนับสนุน Chrome เต็มรูปแบบ 1 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเต็มรูปแบบ 1 | การสนับสนุน IE เต็มรูปแบบ ใช่ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | รองรับ WebView Android เต็มรูปแบบ ใช่ | รองรับ Chrome Android เต็มรูปแบบใช่ | Firefox Android รองรับเต็มรูปแบบ 4 | รองรับ Opera Android เต็มรูปแบบ ใช่ | Safari iOS รองรับเต็มรูปแบบ ใช่ | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ |
การสนับสนุน Chrome เต็มรูปแบบ 1 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเต็มรูปแบบ 1 | การสนับสนุน IE เต็มรูปแบบ ใช่ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | รองรับ WebView Android เต็มรูปแบบ ใช่ | รองรับ Chrome Android เต็มรูปแบบใช่ | Firefox Android รองรับเต็มรูปแบบ 4 | รองรับ Opera Android เต็มรูปแบบ ใช่ | Safari iOS รองรับเต็มรูปแบบ ใช่ | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ |
การสนับสนุน Chrome เต็มรูปแบบ 1 | รองรับ Edge เต็มรูปแบบ 12 | Firefox รองรับเต็มรูปแบบ 1 | การสนับสนุน IE เต็มรูปแบบ ใช่ | รองรับ Opera เต็มรูปแบบ ใช่ | รองรับ Safari เต็มรูปแบบ ใช่ | รองรับ WebView Android เต็มรูปแบบ ใช่ | รองรับ Chrome Android เต็มรูปแบบใช่ | Firefox Android รองรับเต็มรูปแบบ 4 | รองรับ Opera Android เต็มรูปแบบ ใช่ | Safari iOS รองรับเต็มรูปแบบ ใช่ | Samsung Internet Android รองรับเต็มรูปแบบ ใช่ |
Chrome รองรับเต็มรูปแบบ 61 | รองรับ Edge เต็มรูปแบบ 16 | Firefox รองรับเต็มที่ 60 รองรับเต็มที่ 60 ไม่รองรับ 54 - 60 พิการ พิการ | IE ไม่มีหมายเลขรองรับ | โอเปร่าสนับสนุนอย่างเต็มที่ 48 | Safari รองรับเวอร์ชัน 10.1 เต็มรูปแบบ | WebView Android รองรับเต็มรูปแบบ 61 | Chrome Android รองรับเต็มรูปแบบ 61 | Firefox Android รองรับเต็มรูปแบบ 60 รองรับเต็มรูปแบบ 60 ไม่รองรับ 54 - 60 พิการ พิการ ตั้งแต่เวอร์ชัน 54 ถึงเวอร์ชัน 60 (เฉพาะ): คุณลักษณะนี้อยู่เบื้องหลังการตั้งค่า dom.moduleScripts.enabled (จำเป็นต้องตั้งค่าเป็นจริง) หากต้องการเปลี่ยนการตั้งค่าใน Firefox โปรดไปที่ about:config | Opera Android รองรับเต็มรูปแบบ 45 | Safari iOS รองรับเวอร์ชัน 10.3 เต็มรูปแบบ | Samsung Internet Android รองรับเวอร์ชัน 8.0 เต็มรูปแบบ |
Chrome ไม่มีหมายเลขรองรับ | Edge ไม่มีหมายเลขรองรับ | Firefox ไม่มีการสนับสนุน? - 59 | IE ไม่มีหมายเลขรองรับ | Opera ไม่มีหมายเลขรองรับ | Safari ไม่มีหมายเลขรองรับ | WebView Android ไม่มีหมายเลขรองรับ | Chrome Android ไม่มีหมายเลขรองรับ | Firefox Android ไม่รองรับเหรอ? - 59 | Opera Android ไม่รองรับหมายเลข | Safari iOS ไม่มีหมายเลขรองรับ | Samsung Internet Android ไม่รองรับหมายเลข |
ในเบราว์เซอร์รุ่นเก่าที่ไม่รองรับแอตทริบิวต์ async สคริปต์ที่แทรก parser จะบล็อก parser สคริปต์ที่แทรกสคริปต์จะดำเนินการแบบอะซิงโครนัสใน IE และ WebKit แต่พร้อมกันใน Opera และ Firefox รุ่นก่อน 4 ใน Firefox 4 คุณสมบัติ async DOM เป็นค่าเริ่มต้น เป็นจริงสำหรับสคริปต์ที่สร้างสคริปต์ ดังนั้นลักษณะการทำงานเริ่มต้นจะตรงกับลักษณะการทำงานของ IE และ WebKit
หากต้องการร้องขอสคริปต์ภายนอกที่แทรกสคริปต์ให้ดำเนินการตามลำดับการแทรกในเบราว์เซอร์ที่ document.createElement("script").async ประเมินเป็นจริง (เช่น Firefox 4) ให้ตั้งค่า async="false" บนสคริปต์ที่คุณต้องการรักษา คำสั่ง.
อย่าเรียก document.write() จากสคริปต์ async ใน Firefox 3.6 การเรียก document.write() มีผลกระทบที่คาดเดาไม่ได้ ใน Firefox 4 การเรียก document.write() จากสคริปต์ async ไม่มีผลใดๆ (นอกเหนือจากการพิมพ์คำเตือนไปยังคอนโซลข้อผิดพลาด)
Async และ Defer - กลยุทธ์การโหลด JavaScript
JavaScript เป็นส่วนสำคัญของเว็บแอปพลิเคชันสมัยใหม่ และกลยุทธ์ที่เราตัดสินใจใช้สำหรับการโหลดจะส่งผลโดยตรงต่อประสิทธิภาพของแอปพลิเคชันนั้น ๆ ในบทความนี้ เราจะพยายามทำความเข้าใจความแตกต่างที่สำคัญระหว่างแต่ละวิธี ข้อดีและข้อเสีย รวมถึงผลกระทบต่อประสิทธิภาพ และวิธีการเพิ่มประสิทธิภาพสำหรับการโต้ตอบกับหน้าเว็บและเวลาในการโหลด
เพื่อสาธิต ฉันจะสร้างเว็บไซต์ที่ประกอบด้วยการอ้างอิงภายนอกต่อไปนี้ ให้ความสนใจเป็นพิเศษกับขนาดไฟล์ที่เหมาะสม เนื่องจากเวลาในการดาวน์โหลดไฟล์จะเป็นสัดส่วนโดยตรงกับขนาดไฟล์นี้
- HTML - หน้า ~ 1 MB ประกอบด้วยมาร์กอัป/เนื้อหาจริงเพื่อแสดงเอาต์พุตแบบไดนามิกจาก JavaScript
- รูปภาพ - image1.png ~ 5 MB
- JavaScript - file1.JS ~3MB เป็นแกนหลัก (ไฟล์หลัก) ของจาวาสคริปต์และขึ้นอยู่กับการแยกวิเคราะห์ HTML จำเป็นต้องแสดงเนื้อหาไดนามิกหรือติดตั้งส่วนประกอบโต้ตอบ/เชิงมุมบนเพจ
- JavaScript - file2.js ~460B เป็นไฟล์จาวาสคริปต์ขนาดเล็กอิสระที่โต้ตอบกับ dom
- JavaScript - file3.js ~ 1.5 MB - นี่คือไฟล์ js รองและขึ้นอยู่กับ file1.js เพื่อรันโค้ดที่มีลำดับความสำคัญต่ำกว่า โค้ดนี้ไม่จำเป็นทันทีสำหรับการแสดงผลเพจและการโต้ตอบกับผู้ใช้ มันแสดงไอคอนโซเชียลมีเดีย ความคิดเห็น ความช่วยเหลือออนไลน์การเปิดตัวงานการวิเคราะห์บางอย่าง ฯลฯ
Approach-1 [สคริปต์ในส่วนหัว]
ในกรณีแรก เราจะโหลดแท็กสคริปต์ทั้งหมดลงในส่วนหัวของ HTML ของเรา ด้านล่างนี้คือภาพหน้าจอของการวิเคราะห์แท็บเครือข่าย หน้าโครเมี่ยมพร้อมสำหรับการโต้ตอบกับผู้ใช้
ข้อดี:
ลำดับการเรียกใช้โค้ดของไฟล์ JS ต่างๆ จะถูกเก็บรักษาไว้ตามลำดับที่รวมไฟล์ไว้ใน HTML ในตัวอย่างปัจจุบัน แม้ว่า file2 และ file3 จะถูกโหลดก่อน file1 ก็ตาม ลำดับการดำเนินการก็จะถูกต้อง
จุดด้อย:
ในสถานการณ์สมมตินี้ การแยกวิเคราะห์ HTML จะถูกหยุดชั่วคราวจนกว่าสคริปต์ทั้ง 3 ตัวในส่วนหัวจะถูกโหลด แยกวิเคราะห์ และดำเนินการ ว่างเปล่า หน้าจอสีขาวจะแสดงให้ผู้ใช้เห็นแม้ว่าจะดาวน์โหลดไฟล์ HTML ไปแล้วก็ตาม [แต่ไม่ได้แยกวิเคราะห์] สิ่งนี้ไม่ดีต่อการใช้งานอย่างแน่นอน
สคริปต์ข้างต้นทั้งหมดจะไม่สามารถเข้าถึง/จัดการหน้า HTML ได้ เนื่องจาก DOM ยังไม่พร้อม หนึ่งใน แนวทางแก้ไขที่เป็นไปได้วิธีจัดการกับปัญหานี้คือการรับฟังเหตุการณ์ DOMContentLoaded จากนั้นจึงรันโค้ดหลังจากนั้น เหตุการณ์ DOMContentLoaded จะเริ่มทำงานเมื่อมีการโหลดและแยกวิเคราะห์เอกสาร HTML ต้นฉบับโดยสมบูรณ์ โดยไม่ต้องรอให้สไตล์ชีต โหลดรูปภาพให้เสร็จสิ้น
Approach-2 [สคริปต์ตอนท้าย]
เพื่อเอาชนะปัญหา 2 ข้อที่เราเผชิญในแนวทางแรก เราจะโหลดสคริปต์ทั้ง 3 ตัวที่ด้านล่างของแท็ก body
ข้อดี: HTML จะถูกแยกวิเคราะห์ก่อนโหลดสคริปต์ ดังนั้นผู้ใช้จึงสามารถดูเนื้อหาจริงได้ทันที แทนที่จะรอสคริปต์
เนื่องจากสคริปต์ทั้งหมดถูกดำเนินการหลังจากการแยกวิเคราะห์ HTML สคริปต์ทั้งหมดจึงสามารถเข้าถึง DOM เพื่อการจัดการใดๆ ได้ ลำดับการดำเนินการสคริปต์จะยังคงอยู่
จุดด้อย:
ไม่มีการเพิ่มประสิทธิภาพดังกล่าว
แนวทางที่ 3 [การใช้แอตทริบิวต์ Async]
HTML5 เปิดตัวแอตทริบิวต์สคริปต์ async ซึ่งช่วยในการโหลดไฟล์สคริปต์ที่เกี่ยวข้องพร้อมกันบนเธรดอื่นโดยไม่ส่งผลกระทบต่อการแยกวิเคราะห์ HTML
อย่างไรก็ตาม สคริปต์ที่เกี่ยวข้องจะถูกแยกวิเคราะห์และดำเนินการทันทีที่โหลดเสร็จสิ้น ไม่ว่าการแยกวิเคราะห์ HTML จะเสร็จสมบูรณ์หรือไม่ และจะมีการอ้างอิงถึงองค์ประกอบ DOM จนถึงจุดเฉพาะนั้น
ที่นี่คุณจะเห็นได้อย่างชัดเจนว่า file2.js เคยโหลดมาก่อน ไฟล์ HTML- อย่างไรก็ตาม ในขณะที่เบราว์เซอร์กำลังโหลดไฟล์2 เบราว์เซอร์จะไม่หยุดแยกวิเคราะห์ HTML ชั่วคราว และด้วยเหตุนี้ เมื่อถึงเวลาดำเนินการ เบราว์เซอร์จึงมีลิงก์ไปยังตัวยึดตำแหน่ง html เพื่อแนะนำเนื้อหาแบบไดนามิก
ข้อดี: เนื่องจากสคริปต์ถูกโหลดบนเธรดอื่น การแยกวิเคราะห์ HTML จะไม่ถูกหยุดชั่วคราว และผู้ใช้จะสามารถเห็นเนื้อหาได้ทันที แทนที่จะเป็นหน้าจอว่างเปล่าสีขาว ประสิทธิภาพหลักที่เพิ่มขึ้น เช่น เวลา DOMContentLoaded ลดลงจาก 47.68 วินาทีเหลือเพียง 21.12 วินาที และเพิ่มขึ้น ~55%
จุดด้อย:
ลำดับการดำเนินการ JS จะไม่ถูกรักษาไว้ โดยจะทำงานตามลำดับการโหลดที่เหมาะสม แทนที่จะเป็นลำดับสคริปต์ที่รวมไว้ใน HTML รองรับเบราว์เซอร์ - ไม่รองรับเว็บเบราว์เซอร์รุ่นเก่า เช่น IE 9 และต่ำกว่า
จะเกิดอะไรขึ้นหากโหลด JS ก่อนที่จะเข้าถึงองค์ประกอบ DOM ได้ ข้อผิดพลาดจะเกิดขึ้น
หมายเหตุ: การวางสคริปต์ด้วยแอตทริบิวต์ async ที่ด้านล่างของส่วนเนื้อหาจะไม่มีประโยชน์และเทียบเท่ากับแนวทาง-2
แนวทางที่ 4 [การใช้คุณลักษณะ Defer]
คุณลักษณะ Defer จะบังคับให้สคริปต์ดำเนินการหลังจากแยกวิเคราะห์ HTML เสร็จสิ้นแล้วเท่านั้น จุดสำคัญประการหนึ่งที่ต้องพิจารณาที่นี่คือ Chrome ยังไม่รองรับการเลื่อนออกไปและไม่มีผลกระทบต่อระยะเวลาของ DOMContentLoaded อย่างไรก็ตาม มันจะรันสคริปต์เมื่อสิ้นสุดการแยกวิเคราะห์ HTML
ข้อดี:
ลำดับการนำเข้าสคริปต์ยังคงอยู่ ดังนั้น file3.js จะถูกดำเนินการหลังจากที่ file1 โหลดและดำเนินการเสร็จแล้วเท่านั้น แม้ว่า file3 จะถูกโหลดก่อนหน้านี้ก็ตาม
รองรับเบราว์เซอร์ - มี การสนับสนุนที่ดีขึ้นเบราว์เซอร์เปรียบเทียบกับแอตทริบิวต์ async เช่น รองรับบางส่วนใน IE v6-9
สคริปต์สามารถเข้าถึง DOM ได้เนื่องจากจะดำเนินการหลังจากแยกวิเคราะห์ HTML แบบเต็มแล้วเท่านั้น
จุดด้อย:
ตอนแรกผมคิดว่าคงจะล่าช้า ทางเลือกที่ดีที่สุดกว่า async แต่ค้นพบในภายหลังว่า Chrome ยังไม่รองรับ [เวอร์ชัน 71.0.3578.98] และไม่มีผลต่อระยะเวลาของ DOMContentLoaded
อย่างไรก็ตาม มันทำงานได้ตามที่คาดหวังใน Firefox พร้อมการปรับปรุงประสิทธิภาพที่สำคัญ
ข้อสรุป
ขอแนะนำให้วางแท็กสคริปต์ไว้ในส่วนหัวด้วยแอตทริบิวต์ async สำหรับไลบรารีบุคคลที่สามที่ต้องใช้ Google Analytics, Google reCAPTCHA หรือสิ่งอื่นๆ ที่ไม่ต้องการการเข้าถึง DOM เนื่องจากสคริปต์ที่เกี่ยวข้องจะถูกโหลดแบบขนานแต่จะดำเนินการทันที
ใช้ defer สำหรับสคริปต์อื่นๆ ทั้งหมดที่โหลดในส่วนหัว เนื่องจากสคริปต์เหล่านั้นจะถูกโหลดแบบขนาน แต่จะดำเนินการเฉพาะเมื่อการแยกวิเคราะห์ HTML เสร็จสมบูรณ์ และ DOM พร้อมที่จะเข้าถึง/จัดการแล้วเท่านั้น
คุณยังสามารถใช้ชุด Listener DOMContentLoaded ภายในสคริปต์อะซิงก์เพื่อใช้งานฟังก์ชันในภายหลังได้ กรุณาแสดงความคิดเห็นและข้อสรุปของคุณในความคิดเห็นและเรายินดีที่จะพูดคุยกับคุณ
ผู้เขียนเนื้อหานี้คือฉันยูริ Pakholkov ฉันให้บริการเขียนโปรแกรมใน ภาษาจาวา, C++, C# (และให้คำปรึกษาเกี่ยวกับพวกเขาด้วย) และการสร้างเว็บไซต์ ฉันทำงานกับไซต์บน CMS OpenCart, WordPress, ModX และไซต์ที่เขียนเอง นอกจากนี้ ฉันทำงานโดยตรงกับ JavaScript, PHP, CSS, HTML นั่นคือฉันสามารถปรับปรุงเว็บไซต์ของคุณหรือช่วยเขียนโปรแกรมเว็บได้
สคริปต์ปลั๊กอิน (JavaScript) บล็อกการโหลดโค้ด HTML เมื่อเบราว์เซอร์ (parser) เข้าถึงแท็ก เบราว์เซอร์จะหยุดโหลดเนื้อหาของไฟล์และรันโค้ด จากนั้นจึงแยกวิเคราะห์ HTML ต่อไป
ลักษณะการทำงานนี้อาจทำให้การแสดงผล HTML ช้าลงเมื่อมีการโหลดไฟล์ JavaScript จำนวนมากบนเพจ บ่อยครั้งไม่จำเป็นต้องแสดงรหัสของไฟล์เหล่านี้ หน้า HTML- ด้วยเหตุนี้จึงแนะนำให้รวมสคริปต์ไว้ที่ส่วนท้ายของหน้า อย่างไรก็ตาม ไม่สามารถปฏิบัติตามคำแนะนำนี้ได้เสมอไป และในกรณีเช่นนี้ มีวิธีอื่นในการหลีกเลี่ยงการบล็อกการแสดงผล HTML
องค์ประกอบนี้มีแอตทริบิวต์สองรายการ ได้แก่ async และ defer ซึ่งสามารถช่วยให้เราควบคุมวิธีการและเวลาที่ไฟล์จะถูกดาวน์โหลดและดำเนินการได้มากขึ้น
การดำเนินการปกติ ... ... .... คุณลักษณะ asyncเลื่อนแอตทริบิวต์
จะใช้ที่ไหนและอะไร?
ขึ้นอยู่กับสถานการณ์ ลองพิจารณาคำถามหลายข้อในหัวข้อนี้
องค์ประกอบอยู่ที่ไหน?หากไฟล์ JavaScript อยู่หน้าแท็กปิด การใช้ async หรือ defer ไม่สมเหตุสมผล เนื่องจาก ณ จุดนี้ parser ได้แยกวิเคราะห์โค้ด HTML ทั้งหมดแล้ว
สคริปต์มีอยู่ในตัวเองหรือไม่?สำหรับไฟล์ (สคริปต์) ที่ไม่จำเป็นสำหรับสคริปต์อื่นในการทำงานและไม่ได้ขึ้นอยู่กับสคริปต์อื่น แอ็ตทริบิวต์ async จะมีประโยชน์อย่างยิ่ง เนื่องจากในกรณีนี้ไม่สำคัญว่าสคริปต์จะถูกเรียกใช้งาน ณ จุดใด การโหลดแบบอะซิงโครนัสจึงเป็นตัวเลือกที่เหมาะสมที่สุด
ฉันจำเป็นต้องมี DOM ที่โหลดเต็มที่เพื่อให้สคริปต์ทำงานได้หรือไม่หากจำเป็น การใช้ async ก็เหมาะสมเฉพาะในกรณีที่สคริปต์ได้รับการออกแบบสำหรับการโหลดแบบอะซิงโครนัส - เช่น จะรอเหตุการณ์จนกว่าจะโหลด DOM และจากนั้นก็เริ่มทำงานเท่านั้น
หรือคุณสามารถใช้แอตทริบิวต์เลื่อน ในกรณีนี้ คุณสามารถวางการเรียกสคริปต์ที่ใดก็ได้ใน HTML
สคริปต์มีขนาดเล็กหรือไม่?หากสคริปต์มีขนาดค่อนข้างเล็กและขึ้นอยู่กับสคริปต์นั้นหรือขึ้นอยู่กับสคริปต์อื่น ก็สามารถฝังสคริปต์นั้นลงใน HTML ได้โดยตรง (เชื่อมต่อแบบอินไลน์)
รองรับเบราว์เซอร์ 97% การเพิ่มแอตทริบิวต์ defer หรือ async ใน WordPressไม่มีวิธีมาตรฐานในการทำเช่นนี้ ดังนั้นเราจะใช้ script_loader_tag hook:
Add_action("wp_enqueue_scripts", "my_scripts_method"); function my_scripts_method())( // เชื่อมต่อสคริปต์ wp_enqueue_script("my-script", get_template_directory_uri() . "/js/my-script.js"); // เพิ่มแอตทริบิวต์ defer ให้กับสคริปต์ด้วย id `my-script ` add_filter(" script_loader_tag", "change_my_script", 10, 3); ฟังก์ชั่น change_my_script($tag, $handle, $src)( if("my-script" === $handle)( // return str_replace(" src "," async src", $tag); return str_replace(" src", " defer src", $tag); ) return $tag; ) )