CSS和JS在網(wǎng)頁中的放置順序是怎樣的腿准?
- CSS最好放入header中,即放在網(wǎng)頁內(nèi)容(html標(biāo)簽中包含的文字和圖片等)和js腳本之前
<link href="index.css" rel="stylesheet">
- js因?yàn)镴S會(huì)阻塞HTML滓鸠、CSS和圖片的加載雁乡,并且可能修改DOM,所以JS需要放到最后加載糜俗,有四種方式:
- 放在html中</body>前
<script src='index.js'></script>
- 放在head標(biāo)簽內(nèi)踱稍,同時(shí)在script標(biāo)簽內(nèi)添加"defer"或"async"來延遲或異步加載js。
//延遲加載defer:腳本延遲到文檔解析和顯示后執(zhí)行悠抹,有順序
<script defer src='index1.js'></script>
//異步加載async:不保證順序
<script async src='index2.js'></script>
- 用createElement來動(dòng)態(tài)生成珠月,這個(gè)要注意加載順序
- 用ajax加載
解釋白屏和FOUC
白屏的發(fā)生情形:
- 將css文件放在html文檔的最后;
- 使用@import引入css(因?yàn)橥ㄟ^@import引入的css文件會(huì)被最后加載,因此也會(huì)導(dǎo)致白屏);
- 將js文件放在頭部楔敌,而未使用defer或async延遲或異步加載js文件啤挎,導(dǎo)致js阻塞html和css的加載
原因:對于-webkit內(nèi)核的瀏覽器(IE也會(huì)產(chǎn)生),在進(jìn)行網(wǎng)頁渲染時(shí)卵凑,會(huì)同時(shí)加載html和css分別構(gòu)建DOM樹和CSSOM庆聘,等兩者都構(gòu)建完成后,再繪制渲染樹勺卢,然后將頁面顯示出來掏觉。如果在html中將css文件放置在文檔最后,那么將會(huì)導(dǎo)致CSSOM晚于DOM樹的建立值漫,瀏覽器需要等待CSSOM建立澳腹,然后才進(jìn)行網(wǎng)頁內(nèi)容的繪制,這個(gè)等待的過程杨何,沒有內(nèi)容顯示酱塔,就導(dǎo)致了白屏的產(chǎn)生,因此在開發(fā)中危虱,需要將CSS放在head標(biāo)簽內(nèi)羊娃,讓其與html內(nèi)容同時(shí)被加載。js也是同理埃跷,阻塞了CSSO和DOM樹的創(chuàng)建蕊玷。
FOUC:仍是由于瀏覽器的解析造成的邮利,由于瀏覽器先顯示已加載的html內(nèi)容,逐步加載無樣式的內(nèi)容垃帅,等css加載后頁面突然展現(xiàn)樣式延届。主要發(fā)生瀏覽器是火狐瀏覽器。
async和defer的作用是什么贸诚?有什么區(qū)別
async:讓script.js和其他元素異步加載和執(zhí)行
defer:讓script.js的執(zhí)行再所有元素解析完成之后
相同點(diǎn):
- 在加載腳本時(shí)方庭,不阻塞頁面的渲染
- 對于inline script無效
- 使用這兩個(gè)屬性的腳本中不能調(diào)用document.write
- 有腳本的onload事件回調(diào)
區(qū)別:
- 執(zhí)行時(shí)刻
- async屬性會(huì)在腳本下載完成之后異步執(zhí)行,同時(shí)是在window的load事件之前執(zhí)行酱固,因此可能會(huì)出現(xiàn)打亂腳本執(zhí)行順序的情況械念;(無順序)
- defer屬性的腳本是在頁面被解析完成之后才會(huì)被執(zhí)行,按照腳本排列順序執(zhí)行运悲,同時(shí)是在document的DOMcontentLoader之前執(zhí)行(有順序)
- 使用這兩個(gè)屬性會(huì)有的三種情況:
- 如果async為true龄减,那么腳本在加載完成后立刻執(zhí)行
- 如果async為false,defer為true班眯,則腳本在頁面解析完成后執(zhí)行
- 如果async為false欺殿、defer也為false,那么腳本會(huì)阻塞頁面解析鳖敷,轉(zhuǎn)而下載腳本脖苏,并立即執(zhí)行
建議:無論是使用async還是defer,都需要對js文件進(jìn)行整理定踱,哪些文件有依賴棍潘,哪些需要延遲加載,做好js代碼的合并和拆分崖媚,然后再根據(jù)頁面需要合理使用這兩個(gè)屬性
簡述網(wǎng)頁的渲染機(jī)制
- HTML代碼轉(zhuǎn)化成DOM
- CSS代碼轉(zhuǎn)化成CSSOM(CSS Object Model)
- 結(jié)合DOM和CSSOM亦歉,生成一棵渲染樹(包含每個(gè)節(jié)點(diǎn)的視覺信息)
- 生成布局(layout),即將所有渲染樹的所有節(jié)點(diǎn)進(jìn)行平面合成
- 將布局繪制(paint)在屏幕上
生成布局"(flow)和"繪制"(paint)這兩步畅哑,合稱為"渲染"
網(wǎng)頁生成的時(shí)候肴楷,至少會(huì)渲染一次。用戶訪問的過程中荠呐,還會(huì)不斷重新渲染赛蔫。
以下三種情況,會(huì)導(dǎo)致網(wǎng)頁重新渲染泥张。
- 修改DOM
- 修改樣式表
- 用戶事件(比如鼠標(biāo)懸停呵恢、頁面滾動(dòng)、輸入框鍵入文字媚创、改變窗口大小等等)
重新渲染渗钉,就需要重新生成布局和重新繪制。前者叫做"重排"(reflow)钞钙,后者叫做"重繪"(repaint)鳄橘。
需要注意的是声离,"重繪"不一定需要"重排",比如改變某個(gè)網(wǎng)頁元素的顏色瘫怜,就只會(huì)觸發(fā)"重繪"术徊,不會(huì)觸發(fā)"重排",因?yàn)椴季譀]有改變宝磨。但是弧关,"重排"必然導(dǎo)致"重繪"盅安,比如改變一個(gè)網(wǎng)頁元素的位置唤锉,就會(huì)同時(shí)觸發(fā)"重排"和"重繪",因?yàn)椴季指淖兞恕?/p>