ฉันควรใส่แท็ก <script> ในมาร์กอัพ HTML ที่ไหน


1487

เมื่อฝัง JavaScript ในเอกสาร HTML สถานที่ที่เหมาะสมในการวาง<script>แท็กและมี JavaScript อยู่ที่ไหน ฉันดูเหมือนจะจำได้ว่าคุณไม่ควรวางสิ่งเหล่านี้ไว้ใน<head>ส่วน แต่การวางที่จุดเริ่มต้นของ<body>ส่วนนั้นก็ไม่ดีเช่นกันเนื่องจาก JavaScript จะต้องมีการแยกวิเคราะห์ก่อนที่หน้าจะแสดงผลอย่างสมบูรณ์ (หรืออะไรทำนองนั้น) ดูเหมือนว่าจะปล่อยให้ส่วนท้ายของ<body>ส่วนเป็นสถานที่ตรรกะสำหรับ<script>แท็ก

เพื่อที่จะเป็นสถานที่ที่เหมาะสมที่จะนำ<script>แท็ก?

(คำถามนี้อ้างอิงคำถามนี้ซึ่งแนะนำว่าควรทำการย้ายการเรียกฟังก์ชัน JavaScript จาก<a>แท็กไปยัง<script>แท็กฉันใช้ jQuery โดยเฉพาะ แต่คำตอบทั่วไปก็เหมาะสมเช่นกัน)


ในกรณีที่คุณกำลังมองหาวิธีแก้ปัญหาอย่างง่ายและคุณกำลังใช้ตัวสร้างฝั่งเซิร์ฟเวอร์อย่าง Jekyll ฉันแนะนำให้รวมสคริปต์ไว้ด้วย ง่ายกว่านี้มาก!
cregox

คำตอบ:


1861

นี่คือสิ่งที่เกิดขึ้นเมื่อเบราว์เซอร์โหลดเว็บไซต์ที่มี<script>แท็ก:

  1. ดึงหน้า HTML (เช่น index.html)
  2. เริ่มต้นการแยกวิเคราะห์ HTML
  3. parser พบ<script>แท็กที่อ้างอิงไฟล์สคริปต์ภายนอก
  4. เบราว์เซอร์ร้องขอไฟล์สคริปต์ ในขณะเดียวกันตัวแยกวิเคราะห์จะบล็อกและหยุดการแยกวิเคราะห์ HTML อื่น ๆ ในหน้าของคุณ
  5. หลังจากนั้นครู่หนึ่งสคริปต์จะถูกดาวน์โหลดและดำเนินการในภายหลัง
  6. parser แยกวิเคราะห์เอกสาร HTML ที่เหลือต่อไป

ขั้นตอนที่ # 4 ทำให้เกิดประสบการณ์การใช้งานที่ไม่ดี โดยทั่วไปเว็บไซต์ของคุณจะหยุดโหลดจนกว่าคุณจะดาวน์โหลดสคริปต์ทั้งหมด หากมีสิ่งหนึ่งที่ผู้ใช้เกลียดชังก็กำลังรอให้เว็บไซต์โหลด

ทำไมสิ่งนี้ถึงเกิดขึ้นได้?

สคริปต์ใด ๆ สามารถแทรก HTML ของตนเองผ่านทางdocument.write()หรือการเปลี่ยนแปลง DOM อื่น ๆ นี่หมายความว่าตัวแยกวิเคราะห์ต้องรอจนกว่าสคริปต์จะถูกดาวน์โหลดและดำเนินการก่อนจึงจะสามารถแยกวิเคราะห์ส่วนที่เหลือของเอกสารได้อย่างปลอดภัย ท้ายที่สุดสคริปต์อาจแทรก HTML ของตนเองลงในเอกสาร

อย่างไรก็ตามนักพัฒนาจาวาสคริปต์ส่วนใหญ่จะไม่ใช้ DOM ในขณะที่เอกสารกำลังโหลดอีกต่อไป แต่จะรอจนกว่าเอกสารจะถูกโหลดก่อนที่จะแก้ไข ตัวอย่างเช่น:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script src="my-script.js"></script>
    </head>
    <body>
        <div id="user-greeting">Welcome back, user</div>
    </body>
</html>

javascript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

เนื่องจากเบราว์เซอร์ของคุณไม่ทราบ my-script.js จะไม่แก้ไขเอกสารจนกว่าจะมีการดาวน์โหลดและดำเนินการ parser จะหยุดการแยกวิเคราะห์

คำแนะนำโบราณ

วิธีการแบบเก่าในการแก้ปัญหานี้คือการวาง<script>แท็กที่ด้านล่างของคุณ<body>เพราะจะทำให้มั่นใจได้ว่าตัวแยกวิเคราะห์จะไม่ถูกบล็อกจนกว่าจะถึงจุดสิ้นสุด

วิธีการนี้มีปัญหาของตัวเอง: เบราว์เซอร์ไม่สามารถเริ่มดาวน์โหลดสคริปต์จนกว่าเอกสารทั้งหมดจะถูกวิเคราะห์ สำหรับเว็บไซต์ขนาดใหญ่ที่มีสคริปต์และสไตล์ชีทขนาดใหญ่ความสามารถในการดาวน์โหลดสคริปต์โดยเร็วที่สุดเป็นสิ่งที่สำคัญมากสำหรับประสิทธิภาพ หากเว็บไซต์ของคุณไม่โหลดภายใน 2 วินาทีผู้คนจะไปที่เว็บไซต์อื่น

ในโซลูชันที่ดีที่สุดเบราว์เซอร์จะเริ่มดาวน์โหลดสคริปต์ของคุณโดยเร็วที่สุดในขณะเดียวกันก็แยกวิเคราะห์เอกสารที่เหลือของคุณ

แนวทางที่ทันสมัย

วันนี้เบราว์เซอร์รองรับasyncและdeferคุณลักษณะของสคริปต์ คุณลักษณะเหล่านี้บอกเบราว์เซอร์ว่าปลอดภัยในการแยกวิเคราะห์อย่างต่อเนื่องในขณะที่กำลังดาวน์โหลดสคริปต์

async

<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>

สคริปต์ที่มีแอตทริบิวต์ async จะถูกดำเนินการแบบอะซิงโครนัส ซึ่งหมายความว่าสคริปต์จะถูกดำเนินการทันทีที่มีการดาวน์โหลดโดยไม่ปิดกั้นเบราว์เซอร์ในระหว่างนี้
หมายความว่าเป็นไปได้ที่จะดาวน์โหลดและดำเนินการสคริปต์ 2 ก่อนหน้าสคริปต์ 1

ตามhttp://caniuse.com/#feat=script-async , 97.78% ของเบราว์เซอร์ทั้งหมดสนับสนุนสิ่งนี้

Defer

<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>

สคริปต์ที่มีแอตทริบิวต์ defer จะทำงานตามลำดับ (เช่นสคริปต์แรก 1 จากนั้นสคริปต์ 2) สิ่งนี้จะไม่บล็อกเบราว์เซอร์ด้วย

ซึ่งแตกต่างจากสคริปต์ async สคริปต์การเลื่อนจะดำเนินการหลังจากโหลดเอกสารทั้งหมดแล้วเท่านั้น

ตามhttp://caniuse.com/#feat=script-defer 97.79% ของเบราว์เซอร์ทั้งหมดสนับสนุนสิ่งนี้ 98.06% สนับสนุนอย่างน้อยบางส่วน

หมายเหตุสำคัญเกี่ยวกับความเข้ากันได้ของเบราว์เซอร์: ในบางสถานการณ์ IE <= 9 อาจเรียกใช้สคริปต์ที่เลื่อนออกไปตามลำดับ หากคุณต้องการที่จะสนับสนุนเบราว์เซอร์เหล่านั้นโปรดอ่านนี้เป็นครั้งแรก!

ข้อสรุป

สถานะปัจจุบันของศิลปะคือการใส่สคริปต์ใน<head>แท็กและใช้asyncหรือdeferคุณลักษณะ วิธีนี้ทำให้สคริปต์ของคุณสามารถดาวน์โหลดได้โดยไม่ต้องปิดกั้นเบราว์เซอร์ของคุณ

สิ่งที่ดีคือเว็บไซต์ของคุณควรโหลดอย่างถูกต้องในเบราว์เซอร์ 2% ที่ไม่รองรับคุณสมบัติเหล่านี้ในขณะที่เร่งความเร็วอีก 98%


63
ฉันประหลาดใจที่ไม่มีใครอ้างคำอธิบายของ Google ... developers.google.com/speed/docs/insights/BlockingJS
Casey Falk

6
ฉันไม่ชัดเจนในสิ่งที่สัมผัส DOM และสิ่งที่ไม่ คุณช่วยอธิบายได้ไหม ปลอดภัยไหมที่จะทำการโหลด async กับ jquery.js?
ดั๊ก

7
@Doug ตัวอย่างเช่นdocument.writeทำงานบนโดม คำถามไม่ได้หากสคริปต์จัดการ dom แต่เมื่อมันทำ ตราบใดที่การจัดการ Dom เกิดขึ้นหลังจากdomreadyเหตุการณ์ถูกเรียกคุณก็โอเค jQuery เป็นห้องสมุดและไม่ควรจัดการกับตัวเอง
บาร์ต

24
คำตอบนี้ทำให้เข้าใจผิด เบราว์เซอร์สมัยใหม่จะไม่หยุดการแยกวิเคราะห์เมื่อมาถึงแท็กสคริปต์แบบซิงโครนัสซึ่งอาจส่งผลต่อ HTML แต่หยุดการเรนเดอร์ / ดำเนินการและแยกวิเคราะห์ในแง่ดีเพื่อเริ่มดาวน์โหลดทรัพยากรอื่น ๆ
Fabio Beltramini

40
เหตุใดจึงไม่ใช้คุณลักษณะasyncและdeferไม่มีเลย ฉันหมายถึงฉันดูแหล่งข้อมูล HTML มากมายจากอินเทอร์เน็ตและฉันไม่เห็นasyncและdeferแอตทริบิวต์เลย ...
john cj

239

ก่อนแท็กเนื้อหาปิดตามที่ระบุไว้ใน

http://developer.yahoo.com/performance/rules.html#js_bottom

ใส่สคริปต์ที่ด้านล่าง

ปัญหาที่เกิดจากสคริปต์คือบล็อกการดาวน์โหลดแบบขนาน ข้อกำหนด HTTP / 1.1 แนะนำว่าเบราว์เซอร์ดาวน์โหลดไม่เกินสององค์ประกอบในแบบคู่ขนานต่อชื่อโฮสต์ หากคุณแสดงรูปภาพจากชื่อโฮสต์หลายชื่อคุณสามารถดาวน์โหลดมากกว่าสองครั้งเพื่อให้เกิดขนาน ในขณะที่สคริปต์กำลังดาวน์โหลดอย่างไรก็ตามเบราว์เซอร์จะไม่เริ่มการดาวน์โหลดอื่น ๆ แม้แต่ในชื่อโฮสต์ที่ต่างกัน


7
เห็นด้วยกับแนวคิดและคำอธิบาย แต่จะเกิดอะไรขึ้นหากผู้ใช้เริ่มเล่นกับหน้า สมมติว่าฉันเป็นแบบเลื่อนลง AJAX ซึ่งจะเริ่มโหลดหลังจากที่หน้าเว็บปรากฏแก่ผู้ใช้ แต่ในขณะที่มันกำลังโหลดผู้ใช้จะคลิกมัน! และถ้าผู้ใช้ 'ใจร้อนจริงๆ' ส่งแบบฟอร์ม?
Hemant Tank

9
@Hermant ความคิดเห็นเก่า แต่คุณอาจใช้เคล็ดลับปิดการใช้งานฟิลด์โดยค่าเริ่มต้นแล้วเปิดใช้งานพวกเขาโดยใช้ JS เมื่อโหลดเต็ม DOM นั่นคือสิ่งที่ Facebook กำลังทำอยู่ในปัจจุบัน
โนวาโต

2
เพิ่งทดสอบกับ Chrome เพื่อตรวจสอบว่ายังคงเหมือนเดิมหรือไม่ มันคือ. คุณสามารถตรวจสอบความแตกต่างในเวลาโหลดหน้าเว็บของเบราว์เซอร์ของคุณได้ที่นี่ stevesouders.com/cuzillion
cypher

46
หากนี่เป็นแนวปฏิบัติที่ดีที่สุดเหตุใดสแตกล้นจึงรวมแท็กสคริปต์ทั้งหมดไว้ใน <head> :-P
Philip

10
ในบางกรณีโดยเฉพาะอย่างยิ่งในไซต์ ajax ที่หนักการโหลดส่วนหัวอาจส่งผลให้เวลาในการโหลดเร็วขึ้น ดู: encosia.com/dont-let-jquerys-document-ready-slow-you-down (โปรดทราบว่าฟังก์ชั่น "live ()" เลิกใช้แล้วใน jquery แต่บทความยังคงใช้กับ "on ()" หรือ " ฟังก์ชั่นตัวแทน ") อาจต้องโหลด <head> เพื่อรับประกันพฤติกรรมที่ถูกต้องตามที่ @Hermant ชี้ไว้ ในที่สุดmodernizr.com/docsขอแนะนำให้วางสคริปต์ไว้ใน <head> ด้วยเหตุผลที่อธิบายไว้ในเว็บไซต์
นาธาน

76

แท็กสคริปต์ที่ไม่ปิดกั้นสามารถวางได้ทุกที่:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async สคริปต์จะถูกดำเนินการแบบอะซิงโครนัสทันทีที่พร้อมใช้งาน
  • defer สคริปต์ถูกดำเนินการเมื่อเอกสารแยกวิเคราะห์เสร็จแล้ว
  • async defer สคริปต์กลับไปสู่การทำงานแบบเลื่อนลงหากไม่รองรับ async

สคริปต์ดังกล่าวจะถูกดำเนินการแบบอะซิงโครนัส / หลังจากเอกสารพร้อมซึ่งหมายความว่าคุณไม่สามารถทำได้:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

หรือสิ่งนี้:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

หรือสิ่งนี้:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

หรือสิ่งนี้:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

ต้องบอกว่าสคริปต์แบบอะซิงโครนัสนำเสนอข้อดีเหล่านี้:

  • ดาวน์โหลดทรัพยากรแบบขนาน :
    เบราว์เซอร์สามารถดาวน์โหลดสไตล์รูปภาพและสคริปต์อื่น ๆ แบบขนานโดยไม่ต้องรอสคริปต์เพื่อดาวน์โหลดและดำเนินการ
  • ความเป็นอิสระในการสั่งซื้อแหล่งที่มา :
    คุณสามารถวางสคริปต์ไว้ในส่วนหัวหรือเนื้อหาโดยไม่ต้องกังวลเกี่ยวกับการบล็อก (มีประโยชน์หากคุณใช้ CMS) คำสั่งดำเนินการยังคงมีความสำคัญ

เป็นไปได้ที่จะหลีกเลี่ยงปัญหาการดำเนินการตามคำสั่งโดยใช้สคริปต์ภายนอกที่รองรับการเรียกกลับ JavaScript API บุคคลที่สามจำนวนมากในขณะนี้สนับสนุนการดำเนินการที่ไม่ปิดกั้น นี่คือตัวอย่างของการโหลด Google Maps API ถ่ายทอดสด


2
นี่คือคำตอบที่ถูกต้องสำหรับวันนี้การใช้วิธีการนี้หมายความว่าง่ายกว่าที่จะทำให้เครื่องมือของคุณมีอยู่ในตัวโดยไม่จำเป็นต้องทำสิ่งใด<head>รวมถึงตรรกะ
Daniel Sokolowski

1
ฉันสับสนว่าทำไมคุณไม่สามารถใช้asyncหรือdeferเมื่อรวมทั้ง jQuery <script src="jquery.js" async></script>ตามที่คุณระบุในบล็อกที่สองของคุณ: คุณสามารถอธิบายได้ว่าทำไม ฉันคิดว่าฉันต้องมีแท็ก async เพื่อประสิทธิภาพ - ต่อคำตอบที่ยอมรับ - เพื่อให้หน้าของฉันสามารถโหลดได้แม้ในขณะที่ jQuery ยังโหลดอยู่] ขอบคุณ!
elbowlobstercowstand

3
@elbow 99% ของจำนวนครั้ง<script src=jquery.js>ตามด้วย$(function(){ ... })บล็อกบางแห่งในหน้า การโหลดแบบอะซิงโครนัสไม่รับประกันว่าจะโหลด jQuery ในเวลาที่เบราว์เซอร์พยายามแยกวิเคราะห์บล็อกเหล่านั้นซึ่งจะเพิ่ม$ ไม่ได้กำหนดข้อผิดพลาด (คุณอาจไม่ได้รับข้อผิดพลาดหากโหลด jQuery จากแคช) ฉันตอบคำถามเกี่ยวกับการโหลด jQuery $(function(){ ... })ถ่ายทอดสดและรักษา ฉันจะดูว่าฉันสามารถหาได้หรือคุณสามารถดูคำถามนี้: stackoverflow.com/q/14811471/87015
Salman A

1
@SalmanA ขอบคุณ! ใช่ฉันตกอยู่ที่ 99% ฉันต้องใช้jquerylib ในการโหลดจากนั้น.jsสคริปต์ที่เหลืออยู่ของฉัน เมื่อฉันประกาศasyncหรือdeferบนjqueryแท็กสคริปต์ lib สคริปต์ของฉัน.jsไม่ทำงาน ฉันคิดว่า$(function(){ ... })ได้รับการปกป้อง - อย่าเดา วิธีการแก้ปัญหาที่ปัจจุบัน:ผมไม่ได้เพิ่มdeferหรือasyncในjqueryสคริปต์ lib แต่ฉันจะเพิ่มasyncในการติดตามของฉันขึ้น.jsสคริปต์ หมายเหตุ: เหตุผลที่ฉันทำสิ่งนี้เพื่อทำให้ Google Page Speed ​​มีความสุข ขอบคุณอีกครั้งสำหรับความช่วยเหลือ! คำแนะนำอื่น ๆ ยินดีต้อนรับ (หรือลิงก์ไปยังคำตอบก่อนหน้าของคุณ) :)
elbowlobstercowstand

@elbow ดูstackoverflow.com/a/21013975/87015มันจะให้ความคิดแก่คุณเท่านั้น แต่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์ คุณสามารถค้นหา "jquery async loader libraries" แทน
Salman

38

คำแนะนำมาตรฐานสนับสนุนโดย Yahoo! ทีมงานที่ยอดเยี่ยมคือการที่จะนำ<script>แท็กที่ส่วนท้ายของเนื้อหาเอกสารเพื่อไม่ให้บล็อกการแสดงผลของหน้าเว็บ

แต่มีวิธีการใหม่ที่ให้ประสิทธิภาพที่ดีกว่าดังที่อธิบายไว้ในคำตอบนี้เกี่ยวกับความเร็วในการโหลดไฟล์ JavaScript ของ Google Analytics:

มีบางสไลด์ที่ยอดเยี่ยมโดย Steve Souders (ผู้เชี่ยวชาญด้านประสิทธิภาพของลูกค้า) เกี่ยวกับ:

  • เทคนิคต่าง ๆ ในการโหลดไฟล์จาวาสคริปต์ภายนอกแบบขนาน
  • ผลกระทบต่อเวลาโหลดและการแสดงผลหน้าเว็บ
  • ตัวบ่งชี้ "กำลังดำเนินการ" ชนิดใดที่เบราว์เซอร์แสดง (เช่น 'โหลด' ในแถบสถานะเคอร์เซอร์เมาส์นาฬิกาทราย)

25

หากคุณกำลังใช้ JQuery ให้วางจาวาสคริปต์ทุกที่ที่คุณต้องการและใช้งานได้ดีที่สุด $(document).ready()เพื่อให้แน่ใจว่าสิ่งต่าง ๆ ได้รับการโหลดอย่างถูกต้องก่อนที่จะเรียกใช้ฟังก์ชันใด ๆ

ในหมายเหตุด้าน: ฉันชอบแท็กสคริปต์ทั้งหมดของฉันใน<head>ส่วนที่ดูเหมือนจะเป็นสถานที่ที่สะอาดที่สุด


14
ในหัว ... เอ่อ? <header>?
Dan Lugg

7
โปรดทราบว่าการใช้$(document).ready()ไม่ได้หมายความว่าคุณสามารถใส่ JavaScript ของคุณได้ทุกที่ที่ต้องการ - คุณยังต้องใส่มันหลังจาก<script src=".../jquery.min.js">ที่คุณใส่ jQuery $อยู่ด้วย
Rory O'Kane

2
ไม่ควรใส่แท็กสคริปต์ในส่วน <head> ซึ่งจะทำให้การแสดงผลล่าช้าในส่วนที่มองเห็นได้ของหน้าจนกว่าสคริปต์จะโหลด
CyberMonk

ไม่ @Dan headerองค์ประกอบเป็นส่วนหนึ่งของเนื้อหาเอกสาร HTML และควรเกิดขึ้นหนึ่งครั้งหรือมากกว่าภายในแท็ก head bodyelement . The `สำหรับเมตาดาต้าและข้อมูลที่ไม่ใช่เนื้อหาสำหรับเอกสาร มันคือวันนี้ด้วยdeferและasyncเป็นสถานที่ที่เหมาะสำหรับแท็กสคริปต์ headerองค์ประกอบควรมีข้อมูลที่อธิบายถึงส่วนของเอกสารที่ตามมาเท่านั้น
ProfK

1
@ProfK แดนพูดถึงคำถามที่ยังไม่ได้แก้ไขเมื่อเขาโพสต์สิ่งนี้เมื่อ 4 ปีที่แล้ว อย่างที่คุณเห็นคำถามถูกแก้ไขในอีกหนึ่งปีต่อมา
kojow7

18

วิธีการที่ทันสมัยใน 2019 คือการใช้สคริปต์

<script type="module" src="..."></script>

โดยค่าเริ่มต้นโมดูลจะถูกโหลดแบบอะซิงโครนัสและเลื่อนออก เช่นคุณสามารถวางไว้ที่ใดก็ได้และพวกเขาจะโหลดในแบบคู่ขนานและดำเนินการเมื่อหน้าเสร็จสิ้นการโหลด

ความแตกต่างระหว่างสคริปต์และโมดูลอธิบายไว้ที่นี่:

https://stackoverflow.com/a/53821485/731548

การดำเนินการของโมดูลเปรียบเทียบกับสคริปต์อธิบายไว้ที่นี่:

https://developers.google.com/web/fundamentals/primers/modules#defer

การสนับสนุนแสดงอยู่ที่นี่:

https://caniuse.com/#feat=es6-module


ข้อมูลที่ดีที่จะเพิ่มไปยังฐานความรู้
ซาก้า

1
เพิ่งทราบว่าสิ่งนี้จะไม่ทำงานหากคุณแค่ลองใช้ระบบไฟล์ในเครื่องของคุณโดยไม่มีเซิร์ฟเวอร์ ที่เกรงว่าใน Chrome คุณจะได้รับข้อผิดพลาดข้ามที่พยายามโหลด js จาก HTML แม้ว่าทั้งคู่จะมีต้นกำเนิดเดียวกันคือระบบไฟล์ของคุณ
hippietrail

11

XHTML จะไม่ตรวจสอบความถูกต้องหากสคริปต์อยู่ที่อื่นนอกเหนือจากองค์ประกอบส่วนหัว ปรากฎว่ามันสามารถอยู่ได้ทุกที่

คุณสามารถเลื่อนการประมวลผลด้วย jQuery ได้ดังนั้นจึงไม่สำคัญว่าจะวางไว้ที่ใด (ยกเว้นประสิทธิภาพการทำงานเล็กน้อยในระหว่างการวิเคราะห์คำ)


1
XHTML จะตรวจสอบความถูกต้องของแท็กสคริปต์ในเนื้อความทั้งแบบเข้มงวดและในช่วงเปลี่ยนผ่าน อย่างไรก็ตามแท็กสไตล์อาจอยู่ในหัวเท่านั้น
I.devries

11
<script src="myjs.js"></script>
</body>

ควรใช้แท็กสคริปต์เสมอก่อนที่ร่างกายจะปิดหรือด้านล่างในไฟล์HTML

จากนั้นคุณสามารถดูเนื้อหาของหน้าก่อนที่จะโหลดไฟล์js

ตรวจสอบสิ่งนี้หากต้องการ: http://stevesouders.com/hpws/rule-js-bottom.php


2
อันนี้จริงตอบคำถาม ฉันสงสัยว่าเกือบทุกตัวอย่างที่โพสต์ไม่เคยให้บริบทด้านภาพที่เหมาะสมของ "จุดสิ้นสุดของหน้า"
Ken Ingram

1
คำตอบนี้ทำให้เข้าใจผิดมากและอาจผิดมาก บทความใน GoogleและMDNแสดงให้เห็นว่าซิงโครนัส JS (ซึ่งเป็นกรณีนี้) บล็อกการสร้าง DOM และการแยกวิเคราะห์ซึ่งจะทำให้การเรนเดอร์ล่าช้าก่อนเสมอ ดังนั้นคุณไม่สามารถดูเนื้อหาของหน้าจนกว่าจะดึงไฟล์ JS และดำเนินการเสร็จสิ้นโดยไม่คำนึงถึงตำแหน่งที่คุณวางไฟล์ JS ของคุณในเอกสาร HTML ตราบเท่าที่ซิงโครนัส
Lingaraju EV

นอกจากนี้ยังอ้างอิงคะแนนที่ทำในปี 2009 และไม่เกี่ยวข้องอีกต่อไป
toxaq

7

คำตอบทั่วไป (และยอมรับอย่างกว้างขวาง) คือ "ที่ด้านล่าง" เพราะจะโหลด DOM ทั้งหมดก่อนที่จะเริ่มดำเนินการใด ๆ

มีผู้คัดค้านด้วยเหตุผลต่าง ๆ เริ่มต้นด้วยวิธีปฏิบัติที่มีอยู่เพื่อเริ่มต้นการเรียกใช้งานด้วยเจตนาของเหตุการณ์บนหน้าเว็บ


6

ที่ที่ดีที่สุดในการใส่<script>แท็กคือก่อนที่จะปิด</body>แท็กดังนั้นการดาวน์โหลดและการดำเนินการจะไม่ปิดกั้นเบราว์เซอร์เพื่อแยกวิเคราะห์ HTML ในเอกสาร

นอกจากนี้ยังมีการโหลดไฟล์ js ภายนอกได้มันเป็นข้อดีของตัวเองเช่นนั้นจะถูกเก็บไว้โดยเบราว์เซอร์และสามารถเพิ่มความเร็วในการโหลดหน้าครั้งก็แยก HTML และ JavaScript รหัสและความช่วยเหลือในการจัดการฐานรหัสที่ดีกว่า

แต่เบราว์เซอร์ที่ทันสมัยยังสนับสนุนวิธีการอื่นที่เหมาะสมเช่นasyncและdeferโหลดjavascriptไฟล์ภายนอก

Async และ Defer

โดยปกติการเรียกใช้หน้า HTML เริ่มต้นทีละบรรทัด เมื่อพบองค์ประกอบ JavaScript ภายนอกการแยกวิเคราะห์ HTML จะหยุดลงจนกว่าจะดาวน์โหลด JavaScript และพร้อมสำหรับการดำเนินการ การเรียกใช้หน้าปกตินี้สามารถเปลี่ยนแปลงได้โดยใช้deferและasyncแอตทริบิวต์

Defer

เมื่อมีการใช้แอตทริบิวต์ defer จะมีการดาวน์โหลด JavaScript แบบคู่ขนานกับการแยกวิเคราะห์ HTML แต่จะดำเนินการหลังจากการแยกวิเคราะห์ HTML เสร็จสมบูรณ์เท่านั้น

<script src="/local-js-path/myScript.js" defer></script>

Async

เมื่อใช้แอททริบิวต์ async จะทำการดาวน์โหลด JavaScript ทันทีที่พบสคริปต์และหลังจากดาวน์โหลดแล้วจะมีการดำเนินการแบบอะซิงโครนัส (ขนาน) พร้อมกับการแยกวิเคราะห์ HTML

<script src="/local-js-path/myScript.js" async></script>

ควรใช้คุณลักษณะใด

  • หากสคริปต์ของคุณเป็นอิสระจากสคริปต์อื่น ๆ และเป็น modular asyncใช้
  • หากคุณกำลังโหลด script1 และ script2 ด้วยasyncทั้งคู่จะรัน
    คู่ขนานพร้อมกับการแยกวิเคราะห์ HTML ทันทีที่ดาวน์โหลด
    และพร้อมใช้งาน
  • หากสคริปต์ของคุณขึ้นอยู่กับสคริปต์อื่นให้ใช้deferทั้ง:
  • เมื่อ script1 และ script2 ถูกโหลดตามลำดับด้วยdeferดังนั้น script1 จะรับประกันว่าจะทำงานก่อน
  • จากนั้น script2 จะทำงานหลังจาก script1 ทำงานเต็มที่
  • ต้องทำสิ่งนี้หาก script2 ขึ้นอยู่กับ script1
  • หากสคริปต์ของคุณมีขนาดเล็กพอและขึ้นอยู่กับสคริปต์ประเภทอื่นให้asyncใช้สคริปต์ของคุณโดยไม่มีแอตทริบิวต์และวางไว้เหนือasyncสคริปต์ทั้งหมด

การอ้างอิง: knowledgehills.com


3

ขึ้นอยู่กับว่าคุณกำลังโหลดสคริปต์ที่จำเป็นในการกำหนดสไตล์หน้าของคุณ / โดยใช้การกระทำในหน้าของคุณ (เช่นคลิกปุ่ม) ดังนั้นคุณควรวางสคริปต์ไว้ด้านบน หากสไตล์ของคุณคือ CSS 100% และคุณมีตัวเลือกทางเลือกทั้งหมดสำหรับการทำงานของปุ่มคุณสามารถวางไว้ที่ด้านล่าง

หรือสิ่งที่ดีที่สุด (หากไม่ใช่ข้อกังวล) คือคุณสามารถสร้างกล่องใส่คำกริยาให้วางจาวาสคริปต์ที่ด้านล่างของหน้าและทำให้หายไปเมื่อบรรทัดสุดท้ายของสคริปต์โหลด วิธีนี้คุณสามารถหลีกเลี่ยงผู้ใช้ที่ใช้การกระทำในหน้าเว็บของคุณก่อนที่จะโหลดสคริปต์ และยังหลีกเลี่ยงสไตล์ที่ไม่เหมาะสม


3

การรวมสคริปต์ที่ส่วนท้ายจะใช้เป็นหลักซึ่งเนื้อหา / รูปแบบของเว็บไซต์จะแสดงก่อน

รวมถึงสคริปต์ในส่วนหัวโหลดสคริปต์ก่อนหน้าและสามารถนำมาใช้ก่อนการโหลดของเว็บไซต์ทั้งหมด

หากป้อนสคริปต์ในที่สุดการตรวจสอบจะเกิดขึ้นหลังจากการโหลดรูปแบบและการออกแบบทั้งหมดซึ่งไม่ได้รับการยอมรับสำหรับเว็บไซต์ที่ตอบสนองรวดเร็ว


2

ขึ้นอยู่กับสคริปต์และการใช้งานที่เป็นไปได้ที่ดีที่สุด (ในแง่ของการโหลดหน้าเว็บและเวลาในการแสดงผล) อาจจะไม่ใช้ <script> -tag ต่อ se ตามปกติ แต่จะกระตุ้นการโหลดสคริปต์แบบอะซิงโครนัสแบบไดนามิก

มีเทคนิคที่แตกต่างกันบ้าง แต่ตรงไปตรงมาที่สุดคือการใช้ document.createElement ("สคริปต์") เมื่อมีการทริกเกอร์เหตุการณ์ window.onload จากนั้นสคริปต์จะถูกโหลดก่อนเมื่อมีการแสดงผลหน้าเว็บเองดังนั้นจึงไม่ส่งผลกระทบต่อเวลาที่ผู้ใช้ต้องรอให้หน้าเว็บปรากฏ

สิ่งนี้ต้องการให้สคริปต์ไม่จำเป็นสำหรับการเรนเดอร์เพจ

สำหรับข้อมูลเพิ่มเติมดูโพสต์Coupling async สคริปต์โดย Steve Souders (ผู้สร้าง YSlow แต่ตอนนี้ที่ Google)


2
  • หากคุณยังคงสนใจอย่างมากเกี่ยวกับการสนับสนุนและประสิทธิภาพใน IE <10 วิธีที่ดีที่สุดคือให้แท็กสคริปต์ของคุณเป็นแท็กสุดท้ายของเนื้อหา HTML ของคุณ ด้วยวิธีนี้คุณมั่นใจได้ว่าโหลด DOM ที่เหลือและคุณจะไม่ปิดกั้นและแสดงผล

  • หากคุณไม่สนใจอีกต่อไปเกี่ยวกับ IE <10 คุณอาจต้องการวางสคริปต์ไว้ในส่วนหัวของเอกสารของคุณและใช้deferเพื่อให้แน่ใจว่าสคริปต์เหล่านั้นจะทำงานเฉพาะหลังจากที่คุณโหลด DOM ( <script type="text/javascript" src="path/to/script1.js" defer></script>) หากคุณยังต้องการให้โค้ดทำงานใน IE <10 อย่าลืมใส่โค้ดของคุณลงไปในตอนwindow.onloadนี้!


ในคำตอบที่ได้รับการยอมรับนี่จะเรียกว่าเป็น "คำแนะนำโบราณ" หากคุณยังคงหมายความว่าคุณอาจจะต้องอ้างอิงบางอย่าง
dakab

1

สคริปต์บล็อกโหลด DOM จนกว่าจะโหลดและดำเนินการ

หากคุณวางสคริปต์ที่ส่วนท้ายของ<body>DOM ทั้งหมดมีโอกาสโหลดและแสดงผล (หน้าจะ "แสดง" เร็วขึ้น)<script>จะสามารถเข้าถึงองค์ประกอบ DOM ทั้งหมดเหล่านั้นได้

ในทางกลับกันการวาง<body>สคริปต์หลังจากเริ่มต้นหรือสูงกว่าจะเรียกใช้งานสคริปต์ (ซึ่งยังไม่มีองค์ประกอบ DOM)

คุณกำลังรวม jQuery ซึ่งหมายความว่าคุณสามารถวางไว้ที่ใดก็ได้ที่คุณต้องการและใช้. ready ()


1

ฉันคิดว่ามันขึ้นอยู่กับการดำเนินการของหน้าเว็บ หากหน้าเว็บที่คุณต้องการแสดงไม่สามารถแสดงได้อย่างถูกต้องโดยไม่โหลด JavaScript ครั้งแรกคุณควรรวมไฟล์ JavaScript ไว้ก่อน แต่หากคุณสามารถแสดง / แสดงผลหน้าเว็บโดยไม่ต้องดาวน์โหลดไฟล์ JavaScript ในตอนแรกคุณควรใส่รหัส JavaScript ที่ด้านล่างของหน้า เนื่องจากมันจะจำลองการโหลดหน้าเว็บที่รวดเร็วและจากมุมมองของผู้ใช้ดูเหมือนว่าหน้านั้นกำลังโหลดเร็วขึ้น


1

คุณสามารถวางส่วนใหญ่ของ<script>การอ้างอิงในตอนท้ายของ<body>,
แต่หากมีส่วนประกอบที่ถูกใช้สคริปต์ภายนอกบนหน้าของคุณใช้งาน
แล้วพึ่งพาของพวกเขา (ไฟล์ js) ควรจะมาก่อนหน้านั้น (นึกคิดในแท็กหัว)


1

ก่อนที่จะสิ้นสุดของแท็กร่างกายเพื่อป้องกันและการปิดกั้น UI


-1

ในตอนท้ายของเอกสาร HTML

เพื่อที่จะไม่ส่งผลกระทบต่อการโหลดเอกสาร HTML ในเบราว์เซอร์ในขณะดำเนินการ


-1

ที่ที่ดีที่สุดในการเขียนJavaScriptรหัสของคุณอยู่ที่ท้ายเอกสารด้านหลังหรือด้านขวาก่อน</body>แท็กเพื่อโหลดเอกสารก่อนแล้วจึงเรียกใช้รหัส js

<script> ... your code here ... </script>
</body>

และถ้าคุณเขียนในJQueryสิ่งต่อไปนี้สามารถอยู่ในเอกสารหัวและมันจะดำเนินการหลังจากโหลดเอกสาร:

<script>
$(document).ready(function(){
   //your code here...
});
</script>

มันพ่นSyntaxError
Raz

คำตอบของคุณไม่ผิด แต่จำเป็นต้องได้รับการอัปเดตอย่างมาก
Paul Carlton

-2

มันสมเหตุสมผลกว่าที่ฉันจะรวมสคริปต์หลังจาก HTML เพราะส่วนใหญ่ฉันต้องการให้ Dom โหลดก่อนที่ฉันจะเรียกใช้สคริปต์ ฉันสามารถวางไว้ในแท็กหัว แต่ฉันไม่ชอบค่าใช้จ่ายทั้งหมดของฟังการโหลดเอกสาร ฉันต้องการรหัสของฉันจะสั้นและหวานและง่ายต่อการอ่าน

ฉันได้ยินว่าซาฟารีเวอร์ชันเก่านั้นค่อนข้างแปลกเมื่อเพิ่มสคริปต์ของคุณนอกแท็กหัว แต่ฉันบอกว่าใครสนใจ ฉันไม่รู้จักใครที่ใช้อึเก่าคุณ

คำถามที่ดีโดยวิธีการ


-6

คุณสามารถวางตำแหน่งที่คุณต้องการสคริปต์และหนึ่งไม่ดีกว่าการปฏิบัติอื่น

สถานการณ์ดังต่อไปนี้:

หน้าโหลดเป็นเส้นตรง "จากบนลงล่าง" ดังนั้นหากคุณวางสคริปต์ไว้ในส่วนหัวจะทำให้แน่ใจได้ว่าหน้าเว็บจะเริ่มโหลดก่อนทุกอย่างตอนนี้ถ้าคุณวางไว้ในส่วนของร่างกายที่ผสมกับรหัสอาจทำให้หน้าโหลดไม่น่าดู

ระบุการปฏิบัติที่ดีไม่ได้ขึ้นอยู่กับว่า

เพื่อสนับสนุนคุณฉันจะพูดถึงสิ่งต่อไปนี้:

คุณสามารถวาง:

และหน้าจะโหลดเป็นเส้นตรง

เพจถูกโหลดแบบอะซิงโครนัสกับเนื้อหาอื่น

เนื้อหาของหน้าจะโหลดก่อนและหลังการโหลดสคริปต์เสร็จสมบูรณ์

การปฏิบัติที่ดีที่นี่จะเกิดขึ้นเมื่อใด

ฉันหวังว่าฉันจะได้รับประโยชน์อะไรก็แค่ตอบปัญหานี้ให้ฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.