CSS和JS在HTML中的位置
一般CSS放在head里用<style></style>包裹惨险,或用link標(biāo)簽引入css文件
JS因?yàn)闉g覽器渲染機(jī)制會(huì)放在底部</body> 之前胡嘿,就是在加載渲染完HTML迈套、CSS后在加載JS撰筷,不受白屏影響夏块;如果用link標(biāo)簽引入則需要defer/async讓其異步使頁(yè)面不受白屏影響
白屏和FOUC
- 如果把樣式放在底部,對(duì)于IE瀏覽器扬舒,在某些場(chǎng)景下(新窗口打開,刷新等)頁(yè)面會(huì)出現(xiàn)白屏凫佛,而不是內(nèi)容逐步展現(xiàn)讲坎;如果用 @import 標(biāo)簽,即使CSS放入link愧薛,并且放在頭部晨炕,也可能出現(xiàn)白屏
白屏是因?yàn)闉g覽器的渲染機(jī)制,瀏覽器渲染的時(shí)候請(qǐng)求時(shí)間過長(zhǎng)導(dǎo)致白屏毫炉,chrome的渲染流程:html > Dom > css > Cssom > Render Tree > Layout > Painting,可以看出是最后才會(huì)layout然后再painting瓮栗,所以瀏覽器頁(yè)面在css加載渲染完了以后才會(huì)有內(nèi)容顯示,如果瀏覽一些國(guó)外的網(wǎng)站瞄勾,網(wǎng)站被墻费奸,瀏覽器會(huì)一直顯示loding而沒有頁(yè)面顯示,就是因?yàn)榫W(wǎng)頁(yè)響應(yīng)時(shí)間過長(zhǎng)導(dǎo)致白屏进陡;當(dāng)使用@import()時(shí)愿阐,屬性可能導(dǎo)致瀏覽器渲染不及時(shí),又或者我們把標(biāo)簽放在了body的底部位置趾疚,都可能導(dǎo)致不及時(shí)的現(xiàn)象缨历。所以一般用link標(biāo)簽把css樣式文件引入并放置在head里 - FOUC(Flash Of Unstyled Content)無(wú)樣式內(nèi)容閃爍:如果把樣式放在底部,對(duì)于IE瀏覽器在某些場(chǎng)景下(點(diǎn)擊鏈接糙麦,輸入U(xiǎn)RL辛孵,使用書簽進(jìn)入等)會(huì)出現(xiàn)ROUC現(xiàn)象(逐步加載無(wú)樣式的內(nèi)容,等CSS加載后頁(yè)面突然展現(xiàn)樣式)對(duì)于Firefox會(huì)一直表現(xiàn)出FOUC
FireFox的渲染邏輯和Chrome的不太一樣赡磅,一開始Chrome是等待渲染樹和位置計(jì)算好才會(huì)出來網(wǎng)頁(yè)的內(nèi)容魄缚,但到了FireFox每加載一次dom樹就會(huì)重繪一次網(wǎng)頁(yè)樣式,一直到所有內(nèi)容完成為止仆邓,所以一般我們用link把css放在header內(nèi)
async和defer
js對(duì)頁(yè)面加載和渲染有兩個(gè)影響:阻塞后面內(nèi)容的呈現(xiàn)和阻塞其后組件的下載鲜滩,是因?yàn)闉g覽器的渲染機(jī)制:對(duì)于圖片和css伴鳖,在加載時(shí)會(huì)并發(fā)加載(如一個(gè)域名下同時(shí)加載兩個(gè)文件)但在加載JavaScript時(shí)會(huì)禁用并發(fā),并阻止其它內(nèi)容的下載徙硅。所以把JavaScript放入頁(yè)面頂部也會(huì)導(dǎo)致白屏現(xiàn)象
當(dāng)用link標(biāo)簽在head里引入.js文件則需要用async和defer來異步
async:加載渲染后續(xù)文檔元素的過程和.js文件的加載和執(zhí)行并行進(jìn)行(異步)榜聂,不保證順序
defer:加載渲染后續(xù)文檔元素的過程和.js文件的加載和執(zhí)行并行進(jìn)行(異步),但.js文件執(zhí)行需要在所有元素解析完之后嗓蘑,DOMContentLoaded事件觸發(fā)之前完成须肆。
網(wǎng)頁(yè)渲染機(jī)制
- 解析HTML標(biāo)簽,構(gòu)建DOM樹
- 解析CSS標(biāo)簽桩皿,構(gòu)建CSSOM樹
- 把DOM和CSSOM合成Render樹
- 內(nèi)測(cè)測(cè)算數(shù)據(jù)并將頁(yè)面Layout
- 繪制頁(yè)面Painting
具體流程:
瀏覽器通過url獲得html文件后會(huì)從上到下加載并進(jìn)行解析和渲染豌汇。當(dāng)遇到外部css文件或圖片則發(fā)送請(qǐng)求此過程同時(shí)進(jìn)行(異步)。因?yàn)閖s文件有可能要修改DOM所以HTML的加載渲染會(huì)在js文件解析完成后泄隔,因此當(dāng)遇到j(luò)s文件時(shí)HTML會(huì)掛起渲染的線程等js記載完成后繼續(xù)html的加載渲染(白屏原因)拒贱。HTML的渲染過程是將代碼按照深度優(yōu)先遍歷生成DOM tree,CSS加載渲染完后生成CSSOM tree佛嬉,DOM和CSSOM合成Render tree逻澳,然后瀏覽器開始Layout最后Painting