在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事件執行。因此,呵呵。