問題1:CSS和JS在網(wǎng)頁中的放置順序是怎樣的
CSS應(yīng)該放在頁面頂部的
head
標(biāo)簽中
由于Render Tree是由DOM樹和CSSOM樹組合成的,html頁面需要等到CSS解析完后才能完成渲染绑改,所以CSS應(yīng)放在head
標(biāo)簽內(nèi),優(yōu)先下載解析,以避免頁面元素由于樣式缺失造成瞬間的白屏和閃爍。JS應(yīng)該放在
body
的底部
- 因為瀏覽器需要一個穩(wěn)定的dom樹結(jié)構(gòu),而且js中很有可能有代碼直接改變了dom樹結(jié)構(gòu)合愈,瀏覽器為了防止出現(xiàn)js修改dom樹,需要重新構(gòu)建dom樹的情況击狮,所以就會阻塞其他的下載和呈現(xiàn)。
- 將JavaScript放在head內(nèi)和body底部的區(qū)別也在于此益老,放在head里面彪蓬,由于瀏覽器發(fā)現(xiàn)head里面有JavaScript標(biāo)簽就會暫時停止其他渲染行為,等待JavaScript下載并執(zhí)行完成才能接著往下渲染捺萌,而這個時候由于在head里面這個時候頁面是白的档冬;如果JavaScript放在頁面底部,render Tree已經(jīng)完成大部分桃纯,所以此時頁面有內(nèi)容呈現(xiàn)酷誓,即使遇到JavaScript阻塞渲染,也不會有白屏出現(xiàn)态坦。
- 如果CSS和JS都在
head
標(biāo)簽內(nèi)盐数,則應(yīng)將JS放在所有CSS的前面
head里的內(nèi)聯(lián)js只要在所有外聯(lián)css前面,css文件就可以和body里的請求并行伞梯。因為JS 的執(zhí)行有可能依賴最新樣式玫氢。比如,可能會有 var width = $('#id').width(). 這意味著谜诫,JS 代碼在執(zhí)行前漾峡,瀏覽器必須保證在此 JS 之前的所有 css(無論外鏈還是內(nèi)嵌)都已下載和解析完成。這是 CSS 阻塞后續(xù) JS 執(zhí)行的根本原因喻旷。
問題2:解釋白屏和FOUC
- 白屏和fouc并不是bug生逸,而是不同瀏覽器加載和顯示機(jī)制不同造成的。解決方法就是使用
link
標(biāo)簽將樣式表放置在head
標(biāo)簽中 - 白屏
1.當(dāng)把css樣式放在底部或者使用@import
方式引入樣式時一些瀏覽器例如chrome和IE,他的加載和渲染機(jī)制是等css全部加載解析完后再渲染展示頁面槽袄,而這個等待的時間就為白屏烙无。
2.如果把js文件放在頭部,腳本會阻塞后面內(nèi)容的呈現(xiàn)掰伸,腳本會阻塞其后組件的下載皱炉,出現(xiàn)白屏問題。 - FOUC
逐步加載無樣式的內(nèi)容,等CSS加載后頁面突然展現(xiàn)樣式
1.如果把CSS樣式放在底部,對于IE瀏覽器,在某些場景下(點擊鏈接,輸入URL,使用書簽進(jìn)入等),會出現(xiàn) FOUC .
2.另一些瀏覽器例如Firefox,他會在css未加載前先展現(xiàn)頁面,等css加載后再重新對樣式進(jìn)行修改,這就造成了FOUC 狮鸭。
問題3:async和defer的作用是什么合搅?有什么區(qū)別?
如果既不使用 async 也不使用 defer:在瀏覽器繼續(xù)解析頁面之前歧蕉,立即讀取并執(zhí)行腳本灾部。
默認(rèn)引用 script:<script type="text/javascript" src="script.js"></script>
當(dāng)瀏覽器遇到 script 標(biāo)簽時,文檔的解析將停止惯退,并立即下載并執(zhí)行腳本赌髓,腳本執(zhí)行完畢后將繼續(xù)解析文檔。async模式 <script type="text/javascript" src="script.js" async="async"></script>
當(dāng)瀏覽器遇到 script 標(biāo)簽時催跪,文檔的解析不會停止锁蠕,其他線程將下載腳本,腳本下載完成后開始執(zhí)行腳本懊蒸,腳本執(zhí)行的過程中文檔將停止解析荣倾,直到腳本執(zhí)行完畢。defer模式 <script type="text/javascript" src="script.js" defer="defer"></script>
當(dāng)瀏覽器遇到 script 標(biāo)簽時骑丸,文檔的解析不會停止舌仍,其他線程將下載腳本,待到文檔解析完成通危,腳本才會執(zhí)行铸豁。區(qū)別
最主要的區(qū)別就是async是異步下載并立即執(zhí)行,然后文檔繼續(xù)解析菊碟,defer是異步加載后解析文檔节芥,然后再執(zhí)行腳本。
問題3:簡述網(wǎng)頁的渲染機(jī)制
-
瀏覽器解析(包括HTML,SVG,XHTML,CSS,JavaScript等等)
解析HTML代碼框沟,構(gòu)建Document Object Model (DOM)
解析CSS代碼藏古,構(gòu)建CSS Object Model (CSSOM)
JavaSript通過API操作DOM和CSSOM,
渲染樹構(gòu)建過程如下:
布局階段
在屏幕上繪制渲染樹中的所有節(jié)點的幾何屬性,比如: 位置忍燥,寬高拧晕,大小等等繪制元素
繪制所有節(jié)點的可視屬性,比如:顏色梅垄,背景厂捞,邊框输玷,背景圖等,這期間可能會產(chǎn)生多個圖層(堆疊上下文)靡馁。合并渲染層
把以上繪制的所有圖層(類似于PhotoShop中的“圖層”)合并,最終輸出一張圖片欲鹏。
文/饑人谷小霾(簡書作者)著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)臭墨,并標(biāo)注“簡書作者”赔嚎。