CSS和JS在網(wǎng)頁中的放置順序是怎樣的聪黎?
-
JS一般放置在</body>標(biāo)簽之前或添加defer屬性
- JS是阻塞加載莉掂,會阻塞DOM樹或阻塞渲染樹的構(gòu)建。
- JS 可能會修改 DOM,如果在DOM樹加載完成前修改DOM會導(dǎo)致JS代碼無效溪胶。
- JS可能會通過操作DOM對象的class來改變DOM,因此必須保證CSS在JS之前加載和解析完成稳诚。
-
CSS一般放置在head標(biāo)簽內(nèi)
由于Render Tree是由DOM樹和CSSOM樹組合成的哗脖,html頁面需要等到CSS解析完后才能完成渲染,所以CSS應(yīng)放在head標(biāo)簽內(nèi)采桃,優(yōu)先下載解析懒熙,以避免頁面元素由于樣式缺失造成瞬間的白頁或者給用戶閃爍感。
白屏和FOUC
- 當(dāng)把CSS樣式放在底部或者使用@import方式引入樣式普办、或?qū)S放在頭部造成其他內(nèi)容阻塞加載時:
- 一些瀏覽器例如chrome,他的加載和渲染機(jī)制是等頭部的JS和底部的CSS全部加載解析完后再渲染展示頁面,而這個等待的時間就為白屏工扎。
- 另一些瀏覽器例如Firefox,他會在CSS未加載前先展現(xiàn)頁面,等css加載后再重繪一次,這就造成了FOUC (無樣式內(nèi)容閃爍)。
async和defer的作用是什么衔蹲?有什么區(qū)別
- 當(dāng)瀏覽器碰到<script>標(biāo)簽時:
- 瀏覽器會立即加載并執(zhí)行指定的腳本肢娘,并且阻塞后續(xù)的頁面渲染。
- 有 async時舆驶,加載和渲染后續(xù)文檔元素的過程將和 js腳本 的加載與執(zhí)行并行進(jìn)行(異步)橱健。有 async 的情況下,JavaScript 腳本一旦下載好了就會執(zhí)行沙廉,所以很有可能不是按照原本的順序來執(zhí)行的拘荡。如果 JavaScript 腳本前后有依賴性,使用 async 就很有可能出現(xiàn)錯誤撬陵。
- 有 defer時珊皿,加載后續(xù)文檔元素的過程將和 js腳本 的加載并行進(jìn)行(異步)网缝,但是 js腳本 的執(zhí)行要在DOM加載完成之后,DOMContentLoaded 事件觸發(fā)之前完成蟋定。
簡述網(wǎng)頁的渲染機(jī)制
- 解析html構(gòu)建DOM樹
- 解析CSS構(gòu)建CSSOM樹
- 把DOM和CSSOM組合成渲染樹(Render Tree)
- 在渲染樹的基礎(chǔ)上進(jìn)行布局粉臊,計算每個節(jié)點(diǎn)的幾何結(jié)構(gòu)(Layout Tree)
- 把每個節(jié)點(diǎn)繪制到屏幕上(Painting)