1. CSS和JS在網(wǎng)頁中的放置順序是怎樣的?
CSS必須是在html之前載入嫌蚤,所以放在head標(biāo)簽里摊灭。
JS放在CSS后面,既可以放在head標(biāo)簽里偷崩,也可以放在body標(biāo)簽之后
2. 解釋白屏和FOUC
- 白屏問題: 如果把樣式放在底部辟拷,對于IE瀏覽器,chrome等(css全部加載后再呈現(xiàn),有可能等待長)阐斜,在某些場景下(新窗口打開衫冻,刷新等)頁面會出現(xiàn)白屏,而不是內(nèi)容逐步展現(xiàn)谒出。使用 @import 標(biāo)簽隅俘,即使 CSS 放入 link, 并且放在頭部,也可能出現(xiàn)白屏。 對于圖片和CSS, 在加載時會并發(fā)加載(如一個域名下同時加載兩個文件)笤喳。 但在加載 JavaScript 時为居,會禁用并發(fā),并且阻止其他內(nèi)容的下載. 所以把 JavaScript 放入頁面頂部也會導(dǎo)致 白屏 現(xiàn)象.
- FOUC: Flash of Unstyled Content "無樣式內(nèi)容閃爍“:有些瀏覽器是邊渲染邊呈現(xiàn)杀狡,CSS放置body標(biāo)簽底部蒙畴,會出現(xiàn)加載html結(jié)束后才一次性加載css樣式,從而導(dǎo)致頁面閃爍呜象。
我們了解當(dāng)輸入網(wǎng)址按回車后瀏覽器會向服務(wù)器發(fā)送請求膳凝,然后服務(wù)器返回頁面給瀏覽器八孝,瀏覽器邊下載頁面邊解析邊渲染。邊下載頁面邊解析邊渲染的過程:
- 邊下載邊解析就是邊下載html邊構(gòu)建DOM Tree;
- 瀏覽器以user agent stylesheet(瀏覽器內(nèi)置樣式)為原料構(gòu)建CSSOM Tree;
- DOM Tree+CSSOM Tree構(gòu)建出Render Tree鸠项,然后頁面內(nèi)容渲染出來;
- 當(dāng)解析到inline stylesheet 或 internal stylesheet時干跛,馬上刷新CSSOM Tree,CSSOM Tree或DOM Tree發(fā)生變化時會引起Render Tree變化;
- 當(dāng)解析到external stylesheet時就先加載祟绊,然后如internal stylesheet那樣解析和刷新CSSOM Tree和Render Tree了楼入。
總結(jié):上述步驟5中由于樣式文件存在下載這個延時不確定的階段,因此網(wǎng)絡(luò)環(huán)境不好或樣式資源體積大的情況下我們可以看到樣式閃爍明顯牧抽。
3. async和defer的作用是什么嘉熊?有什么區(qū)別
- 沒有 defer 或 async,瀏覽器會立即加載并執(zhí)行指定的腳本扬舒,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前阐肤,也就是說不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行讲坎。
- 有 async孕惜,加載和渲染后續(xù)文檔元素的過程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)。
- 有 defer晨炕,加載后續(xù)文檔元素的過程將和 script.js 的加載并行進(jìn)行(異步)衫画,但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成瓮栗。
- 如果腳本涉及少量DOM操作削罩,則defer屬性更優(yōu):因為html解析未完成前,可能DOM tree未形成费奸,此時進(jìn)行DOM操作弥激,可能失敗。
如果是多個腳本愿阐,則其執(zhí)行順序為:
a微服、多個defer腳本,根據(jù)HTML5的規(guī)定换况,會按照定義的加載順序职辨,按序執(zhí)行;
b戈二、多個async腳本舒裤,由于加載完成立即執(zhí)行,所以是亂序觉吭;因此其更適合腳本之間無依賴關(guān)系的情況腾供。 - 然后從實(shí)用角度來說呢,首先把所有腳本都丟到 </body> 之前是最佳實(shí)踐,因為對于舊瀏覽器來說這是唯一的優(yōu)化選擇伴鳖,此法可保證非腳本的其他一切元素能夠以最快的速度得到加載和解析节值。
4. 簡述網(wǎng)頁的渲染機(jī)制
瀏覽器將從服務(wù)器獲取的HTML文檔構(gòu)建成文檔對象模型DOM(Document Object Model).
樣式將被載入和解析,構(gòu)成層疊樣式表模型CSSOM(CSS Object Model).
在DOM和CSSOM之上榜聂,渲染樹(rendering tree)將會被創(chuàng)建搞疗,代表一系列將被渲染的對象(這在Webkit內(nèi)核中被稱為renderer或者渲染對象render object,在Gecko內(nèi)核中被稱為框架frame)须肆。渲染樹映射除了不可見元素(例如<head>或者含有display:none;的標(biāo)簽)外的所有DOM結(jié)構(gòu)匿乃。每一段文本字符串都將劃分在不同的渲染對象中,每一個渲染對象都包含了它相應(yīng)的DOM對象以及計算后的樣式豌汇。換句話講幢炸,渲染樹是DOM的直觀表示。
渲染樹的每個元素包含的內(nèi)容都是計算過的拒贱,它被稱之為布局layout.瀏覽器使用一種流式處理的方法宛徊,只需要一次pass繪制操作就可以布局所有的元素(tables需要多次pass繪制,pass表示像素處理和頂點(diǎn)處理)逻澳。
最后布局完成闸天,渲染樹將轉(zhuǎn)化為屏幕上的實(shí)際內(nèi)容,這一步被稱為繪制painting.