-
CSS和JS在網頁中的放置順序是怎樣的?
- CSS應該放在頁面的頂部的head標簽中
由于Render Tree是由DOM樹和CSSOM樹組合成的,html頁面需要等到CSS解析完成才能完成渲染,所以css應該放在head
標簽內,優先下載解析,以避免頁面元素由于樣式缺失造成瞬間的白屏或者給用戶閃爍感。
JS應該放在
<body>
的底部</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
- 瀏覽器的白屏與無樣式內容閃爍(FOUC),是由于瀏覽器加載與顯示頁面方式不同造成的:
在寫HTML代碼時,我們都是將CSS文件的引入位置放在頭部(<head>標簽內部),將js文件的引入位置放在底部(</body>前面)。
含義:不同的瀏覽器對于CSS和HTML的處理方式不同,有的是等待CSS加載完成之后,對HTML元素進行渲染和展示(白屏問題)。有的是先對HTML元素進行展示,然后等待CSS加載完成之后重新對樣式進行修改(FOUC無樣式內容閃爍)
解釋:
1.如果把CSS樣式放在底部,對于IE瀏覽器,在某些場景下(新窗口打開,刷新等)頁面會出現白屏,而不是內容逐步展現,如果使用@import
標簽,即使 CSS 放入link
, 把JavaScript放在head
中,腳本會阻塞后面內容的呈現,腳本會阻塞其后組件的下載,出現白屏問題。
2.如果把CSS樣式放在底部,對于IE瀏覽器,在某些場景下(點擊鏈接,輸入URL,使用書簽進入等),會出現 FOUC 現象(逐步加載無樣式的內容,等CSS加載后頁面突然展現樣式).對于 Firefox 會一直表現出 FOUC 。
- 瀏覽器的白屏與無樣式內容閃爍(FOUC),是由于瀏覽器加載與顯示頁面方式不同造成的:
-
async
和defer
的作用是什么?有什么區別
作用: async和
defer``可以達到不阻塞渲染的效果。
- 帶有
defer
屬性的<script>
的標簽可以放置在文檔的任何位置。對應的JavaScript文件將在頁面解析到<script>
標簽時開始下載,但不會執行,直到DOM加載完成,即onload事件觸發前才會被執行。當一個帶有defer
屬性的JavaScript文件下載時,它不會阻塞瀏覽器的其他進程,因此這類文件可以與其他資源文件一起并行下載。
但是
defer
屬性只被IE4和Firefox 3.5更高版本的瀏覽器所支持,所以它不是一個理想的跨瀏覽器解決方案。在其他瀏覽器中,defer
屬性會被直接忽略,因此<script>
標簽會以默認的方式處理,也就是說會造成阻塞。然而,如果你的目標瀏覽器支持的話,這仍然是個有用的解決方案。
-
async
的作用和defer
一樣,能夠異步地加載和執行腳本,不因為加載腳本而阻塞頁面的加載。
但是
在有
async
的情況下,JavaScript腳本一旦下載好了就會執行,所以很有可能不是按照原本的順序來執行的。如果JavaScript腳本前后有依賴性,使用async
就很有可能出行錯誤。
-
簡述網頁的渲染機制
- 解析html構建DOM樹
- 解析CSS構建CSSOM樹
- 把DOM和CSSOM組合成渲染樹(Render Tree)
- 在渲染樹的基礎上進行布局,計算每個節點的幾何結構(Layout Tree)
- 把每個節點繪制到屏幕上(Painting)
文章著作權歸饑人谷_sunny和饑人谷所有,轉載須說明來源