跳至主要内容

請描述 <script>, <script async><script defer> 的差異為何?

透過<script>我們可以適當的控制腳本在瀏覽器載入的時機。

<script>

這是預設的腳本加載方式,在網頁渲染的過程中,會使用 <script> 在 HTML 中載入 Javascript,當執行到<script>時,瀏覽器會暫停解析 HTML,開始下載 <script>腳本並且立即執行,直到<script> 執行完畢才會繼續解析 HTML 建立 DOM。但是當需要載入的<script>腳本很多的時候,會阻塞頁面渲染,會導致使用者體驗不佳。

<script src="index.js"></script>
  • 適用於: 需要立即執行的腳本,特別是那些會影響到 HTML 結構的腳本(例如,使用 document.write() 的腳本)。

Non-Blocking:<script async><script defer>

使用 async 屬性和 defer 屬性可以讓 <script> 檔案在一開始就在背景先下載,可以避免腳本阻塞 HTML 解析。

<script async>

async 屬性會非同步下載 <script>腳本,一旦下載好就立刻執行,開始時執行會停止解析 HTML,但下載本身不會阻塞 HTML 的解析。如果有多個 <script> 並不能保證 <script> 間執行的順序,也不確定腳本執行的時候 HTML 是否完全解析完成。

  • 適用於: 不需要依賴 DOM 或者不需要嚴格執行順序的獨立腳本的第三方函式庫,例如:GA。

<script defer>

defer屬性會非同步下載 <script> 腳本,但是與 async 屬性不同的是,defer 屬性不會打斷 DOM 建立的過程,而是等到 HTML 解析完成,並且在 DOMContentLoad 執行之前執行下載好的腳本,另外,defer 會保證 script 是依照 <script> 的順序去執行。

  • 適用於: 依賴 DOM 或是跟其他模組有相互依賴的模組。