瀏覽器是如何渲染網(wǎng)頁(yè)的挎扰?
在學(xué)習(xí)Javascript之前拔恰,我們先要看看瀏覽器如何渲染HTML的文件的或南?首先瀏覽器先通過(guò)網(wǎng)絡(luò)層繁仁,從服務(wù)器端下載html文件掰曾,然后瀏覽器通過(guò)正則進(jìn)行匹配术裸,進(jìn)行語(yǔ)義分析倘是,然后構(gòu)建DOM樹(shù)。接下來(lái)加載資源也就是加載CSS和JS袭艺。
瀏覽器加載CSS的時(shí)候搀崭,有兩種方式:
1. 先把所有的CSS資源加載完成,然后繪制CSSOM樹(shù)。
2. 先按照瀏覽器默認(rèn)的樣式進(jìn)行繪制瘤睹,遇到CSS資源中的樣式升敲,再加載資源樣式。也就是說(shuō)是邊繪制邊加載轰传。
這個(gè)時(shí)候我們就涉及到了CSS的放置方式的問(wèn)題驴党,因?yàn)镃SS的放置前后順序會(huì)引起白屏和FOUC的問(wèn)題。
白屏問(wèn)題
如果把樣式放在底部,對(duì)于IE瀏覽器,在某些場(chǎng)景下(新窗口打開(kāi),刷新等)頁(yè)面會(huì)出現(xiàn)白屏,而不是內(nèi)容逐步展現(xiàn),如果使用 @import標(biāo)簽,即使 CSS 放入 link, 并且放在頭部,也可能出現(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)象(逐步加載無(wú)樣式的內(nèi)容,等CSS加載后頁(yè)面突然展現(xiàn)樣式).對(duì)于 Firefox 會(huì)一直表現(xiàn)出 FOUC .
所以获茬,為了不引起上述的問(wèn)題港庄。我們一般將CSS文件放入head標(biāo)簽內(nèi)。
我們說(shuō)完了如何在HTML中放置CSS的問(wèn)題恕曲,那接下來(lái)還要說(shuō)說(shuō)JS的放置問(wèn)題攘轩。因?yàn)榧虞dCSS屬于加載外部資源,很顯然码俩,JS也屬于外部資源度帮,我們不可能將JS全部寫(xiě)入script標(biāo)簽中。(如果JS需要很大的話)稿存。
其實(shí)我們知道瀏覽器加載JS的時(shí)候笨篷,不會(huì)像加載CSS的時(shí)候可以一次并發(fā)加載2個(gè)或者4個(gè)文件。瀏覽器會(huì)立即加載并執(zhí)行指定的腳本瓣履,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前率翅,也就是說(shuō)不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行袖迎。這時(shí)候如果script標(biāo)簽還有其他元素冕臭,那么瀏覽器就會(huì)解析不到,會(huì)引起白屏現(xiàn)象燕锥。
腳本會(huì)阻塞后面內(nèi)容的呈現(xiàn)
腳本會(huì)阻塞其后組件的下載
和CSS文件的放置正好相反辜贵,JS一定要放到HTML文件的末尾,也就是body文件的最后归形。(雖然script標(biāo)簽可以放置HTML文件的任何地方托慨,但是我們不建議這么做。)
當(dāng)然你如果非要將JS放置在頭部中暇榴,說(shuō)這樣比較美觀厚棵。那么如何放置白屏的問(wèn)題出現(xiàn),我們可以引用兩個(gè)關(guān)鍵字放入script標(biāo)簽中蔼紧。這兩個(gè)關(guān)鍵字是 defter 婆硬、async。
<script async src="script.js"></script>
有 async奸例,加載和渲染后續(xù)文檔元素的過(guò)程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)彬犯。
<script defer src="script.js"></script>
有 defer,加載后續(xù)文檔元素的過(guò)程將和 script.js 的加載并行進(jìn)行(異步),但 script.js 的執(zhí)行要在所有元素解析完成之后躏嚎,DOMContentLoaded 事件觸發(fā)之前完成蜜自。
defer:腳本延遲到文檔解析和顯示后執(zhí)行,有順序
async:不保證順序
這樣瀏覽器加載完了外部資源后卢佣,就會(huì)將DOM樹(shù)和CSS樹(shù)組合構(gòu)建成渲染樹(shù)重荠,渲染樹(shù)的基礎(chǔ)上進(jìn)行布局,計(jì)算每個(gè)節(jié)點(diǎn)的幾何結(jié)構(gòu)虚茶,把每個(gè)節(jié)點(diǎn)繪制到屏幕上戈鲁。
這樣就完成了瀏覽器渲染HTML文件的整個(gè)過(guò)程。當(dāng)然你如果覺(jué)得我講的比較籠統(tǒng)的話嘹叫,可以參考[How browsers work]婆殿。
以上內(nèi)容參考饑人谷課件