CSS和JS在網(wǎng)頁中的放置順序是怎樣的?
CSS放置在<head>中;
JS不嚴格的來說放在那里都可以,但是如果在HTML和CSS沒有讀取完畢的情況插入JS,有可能出現(xiàn)白屏現(xiàn)象,所以最好放置在HTML和CSS之后。
解釋白屏和FOUC
如果把樣式放在底部,對于IE瀏覽器,在某些場景下(新窗口打開,刷新等)頁面會出現(xiàn)白屏,而不是內(nèi)容逐步展現(xiàn),如果使用 @import 標簽,即使 CSS 放入 link, 并且放在頭部,也可能出現(xiàn)白屏。
如果使用import方法對CSS進行導(dǎo)入,會導(dǎo)致某些頁面在Windows 下的Internet Explorer出現(xiàn)一些奇怪的現(xiàn)象:以無樣式顯示頁面內(nèi)容的瞬間閃爍,這種現(xiàn)象稱之為文檔樣式短暫失效(Flash of Unstyled Content),簡稱為FOUC。
async和defer的作用是什么?有什么區(qū)別
1.<script src="example.js"></script>
沒有defer或async屬性,瀏覽器會立即加載并執(zhí)行相應(yīng)的腳本。也就是說在渲染script標簽之后的文檔之前,不等待后續(xù)加載的文檔元素,讀到就開始加載和執(zhí)行,此舉會阻塞后續(xù)文檔的加載;
2.<script async src="example.js"></script>
有了async屬性,表示后續(xù)文檔的加載和渲染與js腳本的加載和執(zhí)行是并行進行的,即異步執(zhí)行;
3.<script defer src="example.js"></script>
有了defer屬性,加載后續(xù)文檔的過程和js腳本的加載(此時僅加載不執(zhí)行)是并行進行的(異步),js腳本的執(zhí)行需要等到文檔所有元素解析完成之后,DOMContentLoaded事件觸發(fā)執(zhí)行之前。
下圖可以直觀的看出三者之間的區(qū)別:

*其中藍色代表js腳本網(wǎng)絡(luò)加載時間,紅色代表js腳本執(zhí)行時間,綠色代表html解析。
從圖中我們可以明確一下幾點:
1.defer和async在網(wǎng)絡(luò)加載過程是一致的,都是異步執(zhí)行的;
2.兩者的區(qū)別在于腳本加載完成之后何時執(zhí)行,可以看出defer更符合大多數(shù)場景對應(yīng)用腳本加載和執(zhí)行的要求;
3.如果存在多個有defer屬性的腳本,那么它們是按照加載順序執(zhí)行腳本的;而對于async,它的加載和執(zhí)行是緊緊挨著的,無論聲明順序如何,只要加載完成就立刻執(zhí)行,它對于應(yīng)用腳本用處不大,因為它完全不考慮依賴。
簡述網(wǎng)頁的渲染機制
1.由從服務(wù)器接收到的 HTML 形成 DOM(文檔對象模型)。
2.樣式被加載和解析,形成 CSSOM(CSS 對象模型)。
3.緊接著 DOM 和 CSSOM 創(chuàng)建了一個渲染樹,這個渲染樹是一些被渲染對象的集合( Webkit 分別叫它們”renderer”和”render object”,而在Gecko 引擎中叫”frame”)。除了不可見的元素(比如 head 標簽和一些有 display:none 屬性的元素),渲染樹映射了 DOM 的結(jié)構(gòu)。在渲染樹中,每一個文本字符串都被當做一個獨立的 renderer。每個渲染對象都包含了與之對應(yīng)的計算過樣式的DOM 對象(或者一個文本塊)。換句話說,渲染樹描述了 DOM 的直觀的表現(xiàn)形式。
4.對每個渲染元素來說,它的坐標是經(jīng)過計算的,這被叫做“布局(layout)”。瀏覽器使用一種只需要一次處理的“流方法”來布局所有元素(tables需要多次處理)。
5.最后,將布局顯示在瀏覽器窗口中,這個過程叫做“繪制(painting)”。