CSS和JS在網頁中的放置順序是怎樣的?
html文件是自上而下的執行方式,但引入的css和javascript的順序有所不同,css引入執行加載時,程序仍然往下執行,而執行到<script>腳本是則中斷線程,待該script腳本執行結束之后程序才繼續往下執行。
所以,大部分網上討論是將script腳本放在<body>之后,那樣dom的生成就不會因為長時間執行script腳本而延遲阻塞,加快了頁面的加載速度。
但又不能將所有的script放在body之后,因為有一些頁面的效果的實現,是需要預先動態的加載一些js腳本。所以這些腳本應該放在<body>之前。
其次,不能將需要訪問dom元素的js放在body之前,因為此時還沒有開始生成dom,所以在body之前的訪問dom元素的js會出錯,或者無效。
解釋白屏和FOUC
- 在寫HTML代碼時,我們都是將CSS文件的引入位置放在頭部(<head>標簽內部),將js文件的引入位置放在底部(</body>前面)。
- 不同的瀏覽器對于CSS和HTML的處理方式不同,有的是等待CSS加載完成之后,對HTML元素進行渲染和展示(白屏問題)。有的是先對HTML元素進行展示,然后等待CSS加載完成之后重新對樣式進行修改(FOUC無樣式內容閃爍)
- 如果把CSS樣式放在底部,對于IE瀏覽器,在某些場景下(新窗口打開,刷新等)頁面會出現白屏,而不是內容逐步展現,如果使用 @import標簽,即使 CSS 放入 link, 并且放在頭部,也可能出現白屏。
- 如果把CSS樣式放在底部,對于IE瀏覽器,在某些場景下(點擊鏈接,輸入URL,使用書簽進入等),會出現 FOUC 現象(逐步加載無樣式的內容,等CSS加載后頁面突然展現樣式).對于 Firefox 會一直表現出 FOUC 。
- 如果把js文件放在頭部,腳本會阻塞后面內容的呈現,腳本會阻塞其后組件的下載,出現白屏問題。
加載異步
<script defer src="script.js"></script>
<script async src="script.js"></script>
- defer和asnyc是腳本異步加載的兩種方式。
- defer,加載后續文檔元素的過程將和 script.js 的加載并行進行(異步),但 script.js 的執行要在所有元素解析完成之后,DOMContentLoaded 事件觸發之前完成。
- async,加載和渲染后續文檔元素的過程將和 script.js 的加載與執行并行進行(異步)。
async和defer的作用是什么?有什么區別
script
當瀏覽器遇到 script 標簽時,文檔的解析將停止,并立即下載并執行腳本,腳本執行完畢后將繼續解析文檔。
defer script
當瀏覽器遇到 script 標簽時,文檔的解析不會停止,其他線程將下載腳本,待到文檔解析完成,腳本才會執行。
async script
當瀏覽器遇到 script 標簽時,文檔的解析不會停止,其他線程將下載腳本,腳本下載完成后開始執行腳本,腳本執行的過程中文檔將停止解析,直到腳本執行完畢。
什么情況下使用 defer 和 async?
- 如果腳本不依賴于任何腳本,并不被任何腳本依賴,那么則使用 defer。
- 如果腳本是模塊化的,不依賴于任何腳本,那么則使用 async。