在前端開發中,<script>
、<script async>
和 <script defer>
都用於在 HTML 文件中嵌入 JavaScript 程式碼,但它們在載入和執行指令碼的方式上有所不同,從而影響頁面的渲染效能和行為。
1. <script>
(預設行為):
- 載入和執行: 瀏覽器解析到
<script>
標籤時,會立即停止解析 HTML,下載指令碼檔案,然後執行指令碼。執行完畢後,瀏覽器才會繼續解析剩餘的 HTML。 - 阻塞: 這是阻塞式的載入方式,意味著在指令碼下載和執行完成之前,頁面渲染會被阻塞。如果指令碼檔案很大或網路速度慢,會導致頁面出現明顯的延遲,使用者體驗不佳。
- 順序執行: 指令碼會按照它們在 HTML 中出現的順序依次下載和執行。
2. <script async>
:
- 載入和執行: 瀏覽器解析到
<script async>
標籤時,會非同步下載指令碼檔案,不會阻塞 HTML 解析。指令碼下載完成後,瀏覽器會立即暫停 HTML 解析並執行指令碼,執行完畢後再繼續解析 HTML。 - 非阻塞: 非同步載入,不會阻塞頁面渲染。
- 執行順序不確定: 多個帶有
async
屬性的指令碼的執行順序是不確定的,它們可能會以任何順序執行,取決於哪個指令碼先下載完成。因此,async
適用於不依賴於其他指令碼或不影響頁面結構的獨立指令碼,例如統計分析指令碼。
3. <script defer>
:
- 載入和執行: 瀏覽器解析到
<script defer>
標籤時,會非同步下載指令碼檔案,不會阻塞 HTML 解析。指令碼下載完成後,會等待 HTML 解析完成,並在DOMContentLoaded
事件觸發之前執行。 - 非阻塞: 非同步載入,不會阻塞頁面渲染。
- 順序執行: 帶有
defer
屬性的指令碼會按照它們在 HTML 中出現的順序執行。這對於需要操作 DOM 或依賴其他指令碼的指令碼非常有用。
總結:
特性 | <script> |
<script async> |
<script defer> |
---|---|---|---|
載入方式 | 同步 | 非同步 | 非同步 |
阻塞 HTML 解析 | 是 | 否 | 否 |
執行時機 | 立即 | 下載完成後立即執行 | HTML 解析完成後,DOMContentLoaded 事件觸發前 |
執行順序 | 按順序 | 不確定 | 按順序 |
適用場景 | 需要立即執行的指令碼,但會阻塞頁面渲染 | 獨立指令碼,例如統計分析指令碼 | 需要操作 DOM 或依賴其他指令碼的指令碼,例如初始化程式碼 |
示例:
<!DOCTYPE html>
<html>
<head>
<title>Script Example</title>
</head>
<body>
<script src="script1.js"></script> <!-- 預設,阻塞 -->
<script async src="script2.js"></script> <!-- 非同步,執行順序不確定 -->
<script defer src="script3.js"></script> <!-- 非同步,按順序執行 -->
</body>
</html>
選擇哪種方式取決於指令碼的功能和它們之間的依賴關係。如果指令碼之間沒有依賴關係且不影響頁面渲染,可以使用 async
。如果指令碼需要操作 DOM 或依賴其他指令碼,最好使用 defer
。 儘量避免使用預設的 <script>
方式,除非指令碼必須立即執行並且可以接受阻塞頁面渲染。