javaScript標籤的defer和async

在HTML裏面使用javaScript有兩種方式:java

1: 經過<script>元素直接嵌入一段代碼
2: 經過<script>元素的src屬性引入外部js文件

當咱們經過<script>元素引入外部js文件的時候,<script>元素自己的兩個屬性對整個頁面的解析,js文件自己的下載和執行都會產生影響,這兩個屬性就是:defer, async
接下來的文章對js全部可能的狀況一一總結
1: 經過<script>元素直接嵌入一段代碼瀏覽器

<script>
    (function(){alert('hello')})()
</script>
<script>
    (function(){alert('javaScript')})()
</script>

以上的一段代碼,若是是放在<head>裏面,那麼頁面的解析(頁面的解析是遇到<body>開始)就要等這兩段script執行完了纔會開始,而且規定那個先出現就先執行哪一個,因此以上代碼會先執行alert('hello'),再執行alert('javaScript')異步

若是上面的代碼是放在body裏面, 那上面代碼的存在則會直接致使頁面的解析,要等這段js代碼執行完了,再繼續頁面解析的工做。async

3:經過<script>元素的src屬性引入外部js文件,可是沒有defer和asyncspa

<script src="./static/js/a.js"></script>
<script src="./static/js/b.js"></script>

以上的狀況瀏覽器會按照文件出現的前後順序去下載和執行代碼,意思就是b.js會在a.js執行完以後再執行。
若是上述代碼是放在body裏面,那麼它也是阻塞的,若是用圖表示的話就是:
圖片描述code

**2:經過<script>元素的src屬性引入外部js文件,可是有async事件

<script src="./static/js/a.js" async></script>
<script src="./static/js/b.js" async></script>

遇到帶有async屬性的<script>標籤,表示這個js文件的下載是異步的,意思就是它不會阻塞頁面的解析,可是它一旦下載完,他的js代碼就會被當即執行。若是用圖表示的話就是:圖片

圖片描述

從這個圖對比上面的第2種狀況,能夠看出,在下載js文件的時候,頁面的解析依然是在執行的,只是下載完以後js的執行會阻塞頁面的解析。
若是遇到多個帶async的<script>標籤,那麼他們的執行順序是沒法保證的。就像上面的代碼,沒法保證a.js必定會在b.js前面執行。ip

4: 2:經過<script>元素的src屬性引入外部js文件,可是沒有deferit

<script src="./static/js/a.js" defer></script>
<script src="./static/js/b.js" defer></script>

先來看一下defer的圖像表示:
圖片描述

defer只在<script>經過src去引入外部js文件時候纔會起做用。當<script>的type=module的時候,defer也會被忽略,由於type=module的時候,<script>會按照defer那樣的特性工做。

帶有defer的<script>元素的下載一樣不會阻塞頁面的解析,而且它的執行也不會,由於它是等頁面解析完成以後再執行的。若是遇到多個帶defer的<script>元素,js代碼的執行也會按照定義的順序去執行。可是這兩個腳本都會先於DOMContentLoaded事件執行。

**BUT, 在現實世界中,帶defer的script不必定按照順序執行,也不必定會先於DOMContentLoaded事件執行。因此,呵呵。

相關文章
相關標籤/搜索