script標簽加載順序(defer & async)


script 擁有的屬性

  • async:可選,表示應該立即下載腳本,但不應妨礙頁面中的其他操作,比如下載其他資源或等待加載其他腳本。只對外部腳本文件有效。
  • charset:可選。表示通過 src 屬性指定的代碼的字符集。由於大多數瀏覽器會忽略它的值,因此這個屬性很少有人用。
  • defer:可選。表示腳本可以延遲到文檔完全被解析和顯示之后再執行。只對外部腳本文件有效。IE7 及更早版本對嵌入腳本也支持這個屬性。
  • language: 已廢棄。原來用於表示編寫代碼使用的腳本語言(如 JavaScript 、 JavaScript1.2 或 VBScript )。大多數瀏覽器會忽略這個屬性,因此也沒有必要再用了。
  • src:可選。表示包含要執行代碼的外部文件。
  • type:可選。可以看成是 language 的替代屬性;表示編寫代碼使用的腳本語言的內容類型(也稱為 MIME 類型)。雖然 text/javascript 和 text/ecmascript 都已經不被推薦使用,但人們一直以來使用的都還是 text/javascript 。實際上,服務器在傳送 JavaScript 文件時使用的 MIME 類型通常是 application/x–javascript ,但在 type 中設置這個值卻可能導致腳本被忽略。另外,在非IE瀏覽器中還可以使用以下值: application/javascript 和 application/ecmascript 。考慮到約定俗成和最大限度的瀏覽器兼容性,目前 type 屬性的值依舊還是 text/javascript 。不過,這個屬性並不是必需的,如果沒有指定這個屬性,則其默認值仍為text/javascript 。

引入方式 JavaScript 的兩種方式

內聯形式

這種方式指的是在 html 文件中,添加一個<script></scritp>標簽,然后將 JavaScript代碼直接寫在里面

外置形式

外置形式是將 JavaScript 代碼寫在外部的一個文件里面,在 html 文件中通過 <script> 標簽的 src 屬性引入

兩種引入形式的比較

對於這兩種方式,毫無疑問,外置形式明顯好於內聯形式,主要表現為以下方面:

  • 可維護性:外置 Javascript 文件可以被多個頁面調用而不用在每個頁面上反復地書寫.如果有需要改變的部分,你只需要在一處修改即可.所以外置JavaScript 導致代碼工作量減少,進而使得維護手續也更加方便。
  • 可緩存:瀏覽器能夠根據具體的設置緩存鏈接的所有外部 JavaScript文件。也就是說,如果有兩個頁面都使用同一個文件,那么這個文件只需下載一次。因此,最終結果就是能夠加快頁面加載的速度。
  • 關注點分離:將 JavaScript 封裝在外部的.js文件遵循了關注點分離的法則.總體來說,分離 HTML,CSS 和 JavaScript 從而讓我們更容易操縱他們.而且如果是多名開發者同步工作的話,這樣也更方便。

<script> 標簽加載順序

如果要談<script> 標簽加載順序問題,首先要談的就是標簽的位置,因為標簽的位置對於JavaScript加載順序來說有着很重要的影響。

#####標簽位置
<script> 標簽的位置有兩種,一種是方式<head>元素里面,另外一種就是放在<body> 元素中頁面內容的后面,下面將一一介紹這兩種形式:


<script> 標簽放在<head>元素里
<!DOCTYPE html>
<html>

<head>
  <title>Example HTML Page</title>
  <script type="text/javascript" src="example1.js"></script>
  <script type="text/javascript" src="example2.js"></script>
</head>

<body>
  <!-- 這里放內容 -->
</body>

</html>

 

這是一種比較傳統的做法,目的就是把所有外部文件(包括 CSS 文件和 JavaScript 文件)的引用都放在相同的地方.可是,在文檔的 <head> 元素中包含所有 JavaScript 文件,意味着必須等到全部 JavaScript 代碼都被下載、解析和執行完成以后,才能開始呈現頁面的內容(瀏覽器在遇到 <body> 標簽時才開始呈現內容)。對於那些需要很多 JavaScript 代碼的頁面來說,這無疑會導致瀏覽器在呈現頁面時出現明顯的延遲,而延遲期間的瀏覽器窗口中將是一片空白。很明顯,這種做法有着很明顯的缺點,特別是針對於現在的移動端來說,如果超過 1s 還沒有內容呈現的話將是一種很差的用戶體驗。為了避免這個問題,就有了下面這種加載方式。

<script> 標簽放在<body> 元素中頁面內容的后面
<!DOCTYPE html>
<html>

<head>
  <title>Example HTML Page</title>
</head>

<body>
  <!-- 這里放內容 -->
  <script type="text/javascript" src="example1.js"></script>
  <script type="text/javascript" src="example2.js"></script>
</body>

</html>

 

對於這種方式,在解析包含的 JavaScript 代碼之前,頁面的內容將完全呈現在瀏覽器中。而用戶也會因為瀏覽器窗口顯示空白頁面的時間縮短而感到打開頁面的速度加快了

延遲加載

<script>的每個屬性設計來肯定都是有用的,下面我們就來說一說 defer 屬性。
HTML 4.01 為<script> 標簽定義了 'defer 屬性。這個屬性的用途是表明腳本在執行時不會影響頁面的構造。也就是說,腳本會被延遲到整個頁面都解析完畢后再運行。因此,在 <script> 元素中設置defer 屬性,相當於告訴瀏覽器立即下載,但延遲執行,比如:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>script 標簽</title>
  <script defer="defer" type="text/javascript" src="./js/01.js"></script>
  <script defer="defer" type="text/javascript" src="./js/02.js"></script>
</head>

<body>
  <!-- content -->
  <script type="text/javascript" src="./js/03.js"></script>
</body>

</html>

 

在這個例子中,雖然我們把 <script> 元素放在了文檔的 <head> 元素中,但其中包含的腳本將延遲到瀏覽器遇到 標簽后再執行。HTML5 規范要求腳本按照它們出現的先后順序執行,因此第一個延遲腳本會先於第二個延遲腳本執行,而這兩個腳本會先於 DOMContentLoaded 事件執行。在現實當中,延遲腳本並不一定會按照順序執行,也不一定會在 DOMContentLoaded 事件觸發前執行,因此最好只包含一個延遲腳本。

異步加載

說完了延遲加載,然后我們再說下異步加載,即使用 async屬性。
HTML5 為 <script> 元素定義了 async 屬性。這個屬性與 defer 屬性類似,都用於改變處理腳本的行為。同樣與 defer 類似, async 只適用於外部腳本文件,並告訴瀏覽器立即下載文件,下載完成后立即執行。但與 defer不同的是,標記為 async 的腳本並不保證按照指定它們的先后順序執行。例如:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>script 標簽</title>
  <script async type="text/javascript" src="./js/01.js"></script>
  <script async type="text/javascript" src="./js/02.js"></script>
</head>

<body>
  <!-- content -->
</body>

</html>

 

在以上代碼中,可能由於 01.js 下載時間比較長,由於兩個 <script> 標簽都是異步執行,互不干擾,因此 02.js 可能就會先於 01.js 執行。因此,確保兩者之間互不依賴非常重要。指定 async 屬性的目的是不讓頁面等待兩個腳本下載和執行,從而異步加載頁面其他內容。為此,建議異步腳本不要在加載期間修改 DOM。

小結

    • 所有 <script> 標簽引進的 JavaScript 會按照他們引入的順序依次被解析,在沒有使用 defer 或者 async 的情況下,只有在解析完前面 <script> 元素中的代碼之后,才會開始解析后面 <script> 元素中的代碼。
    • 由於瀏覽器會先解析完不使用 defer 屬性的<script> 元素中的代碼,然后再解析后面的內容,所以一般應該把<script> 元素放在頁面最后,即主要內容后面, </body> 標簽前面。
    • 使用 defer 屬性可以讓腳本在文檔完全呈現之后再執行,延遲腳本總是按照指定它們的順序執行
      -使用 async 屬性可以表示當前腳本不必等待其他腳本,也不必阻塞文檔呈現。不能保證異步腳本按照它們在頁面中出現的順序執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM