CSS和JS在網頁中的放置順序是怎樣的?
- CSS應該放在頁面頂部的head標簽中
由于Render Tree是由DOM樹和CSSOM樹組合成的,html頁面需要等到CSS解析完后才能完成渲染,所以CSS應放在head標簽內,優先下載解析,以避免頁面元素由于樣式缺失造成瞬間的白頁或者給用戶閃爍感。
- JS應該放在body的底部
因為瀏覽器需要一個穩定的dom樹結構,而且js中很有可能有代碼直接改變了dom樹結構,瀏覽器為了防止出現js修改dom樹,需要重新構建dom樹的情況,所以就會阻塞其他的下載和呈現。
將JavaScript放在head內和body底部的區別也在于此,放在head里面,由于瀏覽器發現head里面有JavaScript標簽就會暫時停止其他渲染行為,等待JavaScript下載并執行完成才能接著往下渲染,而這個時候由于在head里面這個時候頁面是白的;如果將JavaScript放在頁面底部,render Tree已經完成大部分,所以此時頁面有內容呈現,即使遇到JavaScript阻塞渲染,也不會有白屏出現 - 如果CSS和JS都在head標簽內,則應將JS放在所有CSS的前面
JS的執行有可能依賴最新樣式。比如,可能會有var width=$('#id').width,這意味著,JS代碼在執行前,瀏覽器必須保證在此JS之前的所有CSS(無論外鏈還是內嵌)都已下載和解析完成。
把JS放在CSS后會導致頁面阻塞,去等待CSS的下載。
另外如果要在head引入JS盡量將JS內嵌。
解釋白屏和FOUC
當把CSS樣式放在底部或者使用@import方式引入樣式、或將JS放在頭部造成其他內容阻塞加載時:
1.一些瀏覽器例如chrome,他的加載和渲染機制是等頭部的JS和底部的CSS全部加載解析完后再渲染展示頁面,而這個等待的時間就為白屏。
2.另一些瀏覽器例如Firefox,他會在CSS未加載前先展現頁面,等css加載后再重繪一次,這就造成了FOUC (無樣式內容閃爍)。
*所以為了避免這些問題,最好使用link標簽將CSS樣式表放在文檔的head中,將JS放置在</body>標簽之前、body標簽中html內容的后面。
async和defer的作用是什么?有什么區別
- script :瀏覽器會立加載并執行相應腳本,阻塞后續文檔的加載。
- script async :后續文檔的加載和渲染與js加載和執行同步進行,即異步執行。
async是一個亂序執行方式,對它來說腳本的加載和執行是緊緊挨著的,所以不管你聲明的順序如何,只要它加載完了就會立刻執行,async 對于應用腳本的用處不大,因為它完全不考慮依賴(哪怕是最低級的順序執行),不過它對于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合適的。 -
script defer :后續文檔的加載和渲染與js加載并行,js在后續文檔加載完畢后執行。
簡述網頁的渲染機制
1.解析CSS構建CSSOM樹
2.把DOM和CSSOM組合成渲染樹(Render Tree)
3.在渲染樹的基礎上進行布局,計算每個節點的幾何結構(Layout Tree)
4.把每個節點繪制到屏幕上(Painting)