โหลดข้อความ 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

องค์ประกอบยังสามารถใช้กับภาษาอื่นได้เช่นภาษาการเขียนโปรแกรม GLSL shader ของ WebGL เนื้อหาข้อมูลเมตา เนื้อหาโฟลว์ เนื้อหาการใช้ถ้อยคำ สคริปต์ไดนามิก เช่น text/javascript ไม่มี จำเป็นต้องมีทั้งแท็กเริ่มต้นและแท็กปิด องค์ประกอบใดๆ ที่ยอมรับเนื้อหาข้อมูลเมตา หรือองค์ประกอบใดๆ ที่ยอมรับเนื้อหาการใช้ถ้อยคำ ไม่มี
หมวดหมู่เนื้อหา
เนื้อหาที่ได้รับอนุญาต
การละเว้นแท็ก
ผู้ปกครองที่ได้รับอนุญาต
บทบาท ARIA ที่ได้รับอนุญาต
อินเตอร์เฟซโดม
องค์ประกอบ HTMLScript

คุณสมบัติ 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สคริปต์ อะซิงโครนัส ครอสออริจิน เลื่อนออกไป ความซื่อสัตย์ ภาษา

เลิกใช้แล้ว ไม่ได้มาตรฐาน

โนโมดูล

การทดลอง

นโยบายผู้อ้างอิง src ข้อความ พิมพ์ ประเภทโมดูล type: พารามิเตอร์ version ของแอ็ตทริบิวต์ type

ไม่ได้มาตรฐาน

การสนับสนุน Chrome เต็มรูปแบบ 1รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเต็มรูปแบบ 1

หมายเหตุ

สนับสนุนอย่างเต็มที่1

หมายเหตุ

หมายเหตุ เริ่มต้นใน Firefox 4 การแทรกองค์ประกอบที่สร้างขึ้นโดยการเรียก document.createElement("script") จะไม่บังคับใช้การดำเนินการตามลำดับการแทรกอีกต่อไป การเปลี่ยนแปลงนี้ช่วยให้ Firefox ปฏิบัติตามข้อกำหนดได้อย่างถูกต้อง หากต้องการให้สคริปต์ภายนอกที่แทรกสคริปต์ดำเนินการตามลำดับการแทรก ให้ตั้งค่า .async=false บนสคริปต์เหล่านั้น
การสนับสนุน IE เต็มรูปแบบ ใช่รองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่
การสนับสนุน Chrome เต็มรูปแบบ 1รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเต็มรูปแบบ 1การสนับสนุน IE เต็มรูปแบบ ใช่รองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่รองรับ WebView Android เต็มรูปแบบ ใช่รองรับ Chrome Android เต็มรูปแบบใช่Firefox Android รองรับเต็มรูปแบบ 4รองรับ Opera Android เต็มรูปแบบ ใช่Safari iOS รองรับเต็มรูปแบบ ใช่Samsung Internet Android รองรับเต็มรูปแบบ ใช่
Chrome รองรับเต็มรูปแบบ 30ขอบรองรับเต็ม ≤18Firefox รองรับเต็มรูปแบบ 13IE ไม่มีหมายเลขรองรับโอเปร่าสนับสนุนอย่างเต็มที่ 12รองรับ Safari เต็มรูปแบบ ใช่

หมายเหตุ

สนับสนุนเต็มที่ครับ

หมายเหตุ

หมายเหตุ แอตทริบิวต์ crossorigin ถูกนำมาใช้ใน WebKit ใน WebKit bug 81438
รองรับ WebView Android เต็มรูปแบบ ใช่รองรับ Chrome Android เต็มรูปแบบใช่Firefox Android รองรับเต็มรูปแบบ 14โอเปร่า แอนดรอยด์?ซาฟารี iOS?Samsung Internet Android รองรับเต็มรูปแบบ ใช่
รองรับ Chrome เต็มรูปแบบ ใช่

หมายเหตุ

สนับสนุนเต็มที่ครับ

หมายเหตุ

หมายเหตุ โครเมียม ฉบับที่ #611136 โครเมียม ฉบับที่ #874749
รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเวอร์ชัน 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 บางส่วน 17Firefox รองรับเต็มรูปแบบ 43IE ไม่มีหมายเลขรองรับรองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่WebView Android รองรับเต็มรูปแบบ 45Chrome Android รองรับเต็มรูปแบบ 45Firefox Android รองรับเต็มรูปแบบ 43โอเปร่า แอนดรอยด์?Safari iOS ไม่มีหมายเลขรองรับSamsung Internet Android รองรับเวอร์ชัน 5.0 เต็มรูปแบบ
การสนับสนุน Chrome เต็มรูปแบบ 1รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเต็มรูปแบบ 1การสนับสนุน IE เต็มรูปแบบ ใช่รองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่รองรับ WebView Android เต็มรูปแบบ ใช่รองรับ Chrome Android เต็มรูปแบบใช่Firefox Android รองรับเต็มรูปแบบ 4รองรับ Opera Android เต็มรูปแบบ ใช่Safari iOS รองรับเต็มรูปแบบ ใช่Samsung Internet Android รองรับเต็มรูปแบบ ใช่
Chrome รองรับเต็มรูปแบบ 61รองรับ Edge เต็มรูปแบบ 16Firefox รองรับเต็มที่ 60 รองรับเต็มที่ 60 ไม่รองรับ 55 - 60

พิการ

พิการ
IE ไม่มีหมายเลขรองรับโอเปร่าสนับสนุนอย่างเต็มที่ 48ซาฟารีรองรับเต็มรูปแบบ 11Firefox Android รองรับเต็มรูปแบบ 60 รองรับเต็มรูปแบบ 60 ไม่รองรับ 55 - 60

พิการ

พิการ ตั้งแต่เวอร์ชัน 55 ถึงเวอร์ชัน 60 (เฉพาะ): คุณลักษณะนี้อยู่เบื้องหลังการตั้งค่า dom.moduleScripts.enabled (จำเป็นต้องตั้งค่าเป็นจริง) หากต้องการเปลี่ยนการตั้งค่าใน Firefox โปรดไปที่ about:config
Safari iOS รองรับเต็มรูปแบบ 11
Chrome รองรับเต็มรูปแบบ 70ขอบรองรับเต็ม ≤79Firefox รองรับเต็มรูปแบบ 65IE ไม่มีหมายเลขรองรับรองรับ Opera เต็มรูปแบบ ใช่Safari ไม่มีหมายเลขรองรับรองรับ WebView Android เต็มรูปแบบ 70Chrome Android รองรับเต็มรูปแบบ 70Firefox Android รองรับเต็มรูปแบบ 65โอเปร่า แอนดรอยด์?Safari iOS ไม่มีหมายเลขรองรับSamsung Internet Android รองรับเวอร์ชันเต็ม 10.0
การสนับสนุน Chrome เต็มรูปแบบ 1รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเต็มรูปแบบ 1การสนับสนุน IE เต็มรูปแบบ ใช่รองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่รองรับ WebView Android เต็มรูปแบบ ใช่รองรับ Chrome Android เต็มรูปแบบใช่Firefox Android รองรับเต็มรูปแบบ 4รองรับ Opera Android เต็มรูปแบบ ใช่Safari iOS รองรับเต็มรูปแบบ ใช่Samsung Internet Android รองรับเต็มรูปแบบ ใช่
การสนับสนุน Chrome เต็มรูปแบบ 1รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเต็มรูปแบบ 1การสนับสนุน IE เต็มรูปแบบ ใช่รองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่รองรับ WebView Android เต็มรูปแบบ ใช่รองรับ Chrome Android เต็มรูปแบบใช่Firefox Android รองรับเต็มรูปแบบ 4รองรับ Opera Android เต็มรูปแบบ ใช่Safari iOS รองรับเต็มรูปแบบ ใช่Samsung Internet Android รองรับเต็มรูปแบบ ใช่
การสนับสนุน Chrome เต็มรูปแบบ 1รองรับ Edge เต็มรูปแบบ 12Firefox รองรับเต็มรูปแบบ 1การสนับสนุน IE เต็มรูปแบบ ใช่รองรับ Opera เต็มรูปแบบ ใช่รองรับ Safari เต็มรูปแบบ ใช่รองรับ WebView Android เต็มรูปแบบ ใช่รองรับ Chrome Android เต็มรูปแบบใช่Firefox Android รองรับเต็มรูปแบบ 4รองรับ Opera Android เต็มรูปแบบ ใช่Safari iOS รองรับเต็มรูปแบบ ใช่Samsung Internet Android รองรับเต็มรูปแบบ ใช่
Chrome รองรับเต็มรูปแบบ 61รองรับ Edge เต็มรูปแบบ 16Firefox รองรับเต็มที่ 60 รองรับเต็มที่ 60 ไม่รองรับ 54 - 60

พิการ

พิการ
IE ไม่มีหมายเลขรองรับโอเปร่าสนับสนุนอย่างเต็มที่ 48Safari รองรับเวอร์ชัน 10.1 เต็มรูปแบบWebView Android รองรับเต็มรูปแบบ 61Chrome Android รองรับเต็มรูปแบบ 61Firefox Android รองรับเต็มรูปแบบ 60 รองรับเต็มรูปแบบ 60 ไม่รองรับ 54 - 60

พิการ

พิการ ตั้งแต่เวอร์ชัน 54 ถึงเวอร์ชัน 60 (เฉพาะ): คุณลักษณะนี้อยู่เบื้องหลังการตั้งค่า dom.moduleScripts.enabled (จำเป็นต้องตั้งค่าเป็นจริง) หากต้องการเปลี่ยนการตั้งค่าใน Firefox โปรดไปที่ about:config
Opera Android รองรับเต็มรูปแบบ 45Safari iOS รองรับเวอร์ชัน 10.3 เต็มรูปแบบSamsung Internet Android รองรับเวอร์ชัน 8.0 เต็มรูปแบบ
Chrome ไม่มีหมายเลขรองรับEdge ไม่มีหมายเลขรองรับFirefox ไม่มีการสนับสนุน? - 59IE ไม่มีหมายเลขรองรับOpera ไม่มีหมายเลขรองรับSafari ไม่มีหมายเลขรองรับWebView Android ไม่มีหมายเลขรองรับChrome Android ไม่มีหมายเลขรองรับFirefox Android ไม่รองรับเหรอ? - 59Opera 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; ) )