script標(biāo)簽用于加載腳本與執(zhí)行腳本,在前端開發(fā)中可以說(shuō)是非常重要的標(biāo)簽了。直接使用script腳本的話,html會(huì)按照順序來(lái)加載并執(zhí)行腳本,在腳本加載&執(zhí)行的過(guò)程中,會(huì)阻塞后續(xù)的DOM渲染,造成延遲之類的,就會(huì)使得頁(yè)面白屏。
在介紹他們之前,我們有必要先了解一下頁(yè)面的加載和渲染過(guò)程:
1.解析html文件,創(chuàng)建DOM樹
自上而下解析,遇到任何樣式(link、style)和腳本(script)都會(huì)阻塞
1)css加載不會(huì)阻塞html文件的解析,但會(huì)阻塞dom的渲染
2)css加載會(huì)阻塞后面js語(yǔ)句的執(zhí)行
3)js會(huì)阻塞html的解析和渲染
4)沒(méi)有defer和async標(biāo)簽的script會(huì)立即加載并執(zhí)行
5)有async標(biāo)簽的js,js的加載執(zhí)行和html的解析和渲染并行
6)有defer標(biāo)簽的js,js的加載和html的解析和渲染并行,但會(huì)在html解析完成后執(zhí)行,在觸發(fā)DOMContentLoaded事件前執(zhí)行
7)DOMContentLoaded和onload的區(qū)別:DOMContentLoaded在html解析完畢后執(zhí)行,loload在頁(yè)面完全加載完成后執(zhí)行(包括樣式和圖片)
2.解析css,生成CSSDOM,css對(duì)象模型
3.dom和css合并,構(gòu)建渲染樹(Render Tree)
4.布局(Layout)和繪制(Paint),重繪(repaint)和重排(reflow/回流)
1)重繪:根據(jù)元素的新屬性重新繪制,使元素呈現(xiàn)新的外觀
2)重排:當(dāng)渲染樹中的一部分因?yàn)樵氐囊?guī)模尺寸,布局,隱藏等改變而需要重新構(gòu)建
3)重排必定會(huì)引發(fā)重繪,但重繪不一定會(huì)引發(fā)重排
關(guān)于defer我們需要注意下面幾點(diǎn):
1. defer只適用于外聯(lián)腳本,如果script標(biāo)簽沒(méi)有指定src屬性,只是內(nèi)聯(lián)腳本,不要使用defer
2. 如果有多個(gè)聲明了defer的腳本,則會(huì)按順序下載和執(zhí)行
3. defer腳本會(huì)在DOMContentLoaded和load事件之前執(zhí)行
關(guān)于async,也需要注意以下幾點(diǎn):
1. 只適用于外聯(lián)腳本,這一點(diǎn)和defer一致
2. 如果有多個(gè)聲明了async的腳本,其下載和執(zhí)行也是異步的,不能確保彼此的先后順序
3.async會(huì)在load事件之前執(zhí)行,但并不能確保與DOMContentLoaded的執(zhí)行先后順序,async的執(zhí)行是加載完成就會(huì)去執(zhí)行,而不像defer那樣要等待所有的腳本加載完后按照順序執(zhí)行。