css和js的放置位置、白屏和FOUC、async和defer、簡(jiǎn)述網(wǎng)頁(yè)的渲染機(jī)制、
一、CSS和JS在網(wǎng)頁(yè)中的放置順序是怎樣的?
將CSS使用link標(biāo)簽放在head標(biāo)簽中。
將JS使用script標(biāo)簽包裹或者引入,并且放在body標(biāo)簽的最后。
二、解釋白屏和FOUC
白屏問(wèn)題
- 如果把樣式放在底部,對(duì)于IE瀏覽器,在某些場(chǎng)景下(新窗口打開(kāi),刷新等)頁(yè)面會(huì)出現(xiàn)白屏,而不是內(nèi)容逐步展現(xiàn)
- 如果使用 @import 標(biāo)簽,即使 CSS 放入 link, 并且放在頭部,也可能出現(xiàn)白屏
- JS放在
head部分時(shí),JS的下載會(huì)優(yōu)先于body中內(nèi)容,導(dǎo)致JS腳本阻塞后面內(nèi)容的呈現(xiàn)和其他組件的下載。
FOUC(Flash of unstyled content)無(wú)樣式內(nèi)容閃爍
如果把樣式放在底部,對(duì)于IE瀏覽器,在某些場(chǎng)景下(點(diǎn)擊鏈接,輸入U(xiǎn)RL,使用書(shū)簽進(jìn)入等),會(huì)出現(xiàn) FOUC 現(xiàn)象對(duì)于 Firefox 會(huì)一直表現(xiàn)出 FOUC。
FOUC的表現(xiàn)為——先把HTML解析出來(lái)并渲染到頁(yè)面上,然后不斷加載CSS,每加載一次樣式頁(yè)面就重新繪制一次頁(yè)面,直到所有內(nèi)容加載完成。
三、async和defer的作用是什么?有什么區(qū)別
-
<script src="script.js"></script>
沒(méi)有 defer或 async,瀏覽器會(huì)立即加載并執(zhí)行指定的腳本,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前,也就是說(shuō)不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行。 -
<script async src="script.js"></script>
有 async,加載和渲染后續(xù)文檔元素的過(guò)程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)。 -
<script defer src="myscript.js"></script>
有 defer,加載后續(xù)文檔元素的過(guò)程將和 script.js 的加載并行進(jìn)行(異步),但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成。
藍(lán)色線代表網(wǎng)絡(luò)讀取,紅色線代表執(zhí)行時(shí)間,這倆都是針對(duì)腳本的;綠色線代表 HTML 解析。
此圖告訴我們以下幾個(gè)要點(diǎn):
defer 和 async 在網(wǎng)絡(luò)讀取(下載)這塊兒是一樣的,都是異步的(相較于 HTML 解析)
它倆的差別在于腳本下載完之后何時(shí)執(zhí)行,顯然 defer 是最接近我們對(duì)于應(yīng)用腳本加載和執(zhí)行的要求的
關(guān)于 defer,此圖未盡之處在于它是按照加載順序執(zhí)行腳本的。
async 則是一個(gè)亂序執(zhí)行,反正對(duì)它來(lái)說(shuō)腳本的加載和執(zhí)行是緊緊挨著的,所以不管你聲明的順序如何,只要它加載完了就會(huì)立刻執(zhí)行。
參考來(lái)源(https://segmentfault.com/q/1010000000640869)
四、簡(jiǎn)述網(wǎng)頁(yè)的渲染機(jī)制
- 解析HTML標(biāo)簽,構(gòu)建DOM樹(shù)。
- 解析CSS標(biāo)簽,構(gòu)建CSSOM樹(shù)。
- 將DOM與CSSOM進(jìn)行組合構(gòu)建渲染樹(shù) Render Tree。
- 在渲染樹(shù)的基礎(chǔ)上進(jìn)行布局,計(jì)算每個(gè)節(jié)點(diǎn)的幾何結(jié)構(gòu)。
-
把每個(gè)節(jié)點(diǎn)繪制到屏幕上 (painting)。
對(duì)于Firefox瀏覽器則有所不同
- 解析HTML標(biāo)簽,構(gòu)建DOM樹(shù)。
- 解析CSS標(biāo)簽
- 每解析出一個(gè)CSS標(biāo)簽就與對(duì)應(yīng)的DOM進(jìn)行組合構(gòu)建成渲染樹(shù)的一部分。
- 在渲染樹(shù)的基礎(chǔ)上進(jìn)行布局,計(jì)算每個(gè)節(jié)點(diǎn)的幾何結(jié)構(gòu)。
- 把每個(gè)節(jié)點(diǎn)繪制到屏幕上 (painting)。
