html文檔是自上而下加載的
試想一下,在你的網頁還沒展現出來時,就匆匆忙忙運行了一大堆JavaScript,或者你想先執行完腳本1,再執行腳本2,結果卻不如你所願,這將會給用戶帶來多麼糟糕的體驗!!!
script和DOM是同步加載的
這裏先假設某html的所有JavaScript沒添加window.onload 或 $(function(){})等,由於script和DOM是同步解析的,也就是說後面的dom必須等它前面的所有script全部加載完,再配合前面的css的解析結果構建DOM樹,後面script也必須等它前面的所有dom構建完,再解析該script
按照上面的流程,假如想head裏的script操作某button元素,但是此時的dom卻還沒渲染完,那麼可以在script裏使用onload或者JQuery操作,作用是告訴瀏覽器,我先不執行,我要等到頁面渲染完成再執行,當然,這不能否認html的自上而下執行,只不過執行到該script,瀏覽器先把它放到一邊等頁面加載完執行而已
圖片或視頻的加載是異步的
也就是說在加載css和dom的過程中假如出現圖片鏈接,瀏覽器會額外去下載這個圖片,並且不會阻塞到後面的資源解析,但圖片的加載卻受css樣式的影響,比如用css給圖片定義了寬高,那麼圖片的渲染之前,css必須加載完成
script的執行順序
<script>
alert("test1");
alert!("test2");
alert("test3");
</script>
<script>
alert("test4");
</script>
上面的代碼在瀏覽器瀏覽器只會彈出 “test4”,第一個script遇到錯誤的語法,於是直接報錯並忽略該script塊的執行,而跳轉到下一個script塊執行,也就是說每個script互不影響,但是他們各自的變量等資源卻是共享的
<script>
setTimeout(function(){
alert("test1");
},100);
</script>
<script>
alert("test2");
</script>
上面的代碼會先彈出 test2,再彈出 test1,第一個script要等到100ms纔會執行,於是瀏覽器會等100ms後才把該script裝入到執行隊列,而先把第二個script裝入執行隊列,也就是說,script之間,假如前面的script處於阻塞狀態,那麼就會先執行後面script,直到前面的阻塞結束
window.onload = function(){
setTimeout(function(){alert("test1")},100);
alert("test2");
setTimeout(function(){alert("test3")},100);
alert("test4");
}
上面的代碼彈出順序依次 test2->test4->test1->test3, 同樣的理由,雖然test1在前面,但是被阻塞了100ms,所以瀏覽器會把被阻塞的代碼放到另一個隊列,先執行後面直接可以執行的代碼
外部樣式和外部腳本
外部樣式和外部腳本的加載也是異步的,也就是說在加載外部文件的時候,不會阻塞到後面dom等的解析,外部腳本執行沒有async、defer的屬性時,會被外部樣式阻塞,也就是說要等到外部css加載完纔會執行外部腳本,添加async或defer就不會受到阻塞