爲什麼要把js放在頁面底部,css放在頂部

先了解一下 瀏覽器的渲染原理:

當我們在瀏覽器輸入URL 時,瀏覽器會返回我們一個HTML文檔,將文檔下載下來後,便開始從上到下開始解析。解析完成之後就會生成DOM。如果頁面中有css,會根據css的內容生成cssom, 然後DOM會和cssom結合生成一個渲染樹,最後瀏覽器會根據渲染樹的內容,計算出各個節點的大小和位置繪製在頁面上。

js 會阻礙瀏覽器的解析,解析遇到js會停止渲染,優先去加載或者執行js,處理完畢後再繼續渲染。

如果,js腳本標籤前面有link樣式鏈接,js會等樣式加載和解析完畢纔會執行JS。

在現在瀏覽器中,爲了減緩渲染被阻塞的情況,現代的瀏覽器都使用了猜測預加載。當解析被阻塞的時候,瀏覽器會有一個輕量級的HTML(或CSS)掃描器(scanner)繼續在文檔中掃描,查找那些將來可能能夠用到的資源文件的url,在渲染器使用它們之前將其下載下來。

在這裏我們可以明確DOMContentLoaded所計算的時間,當文檔中沒有腳本時,瀏覽器解析完文檔便能觸發 DOMContentLoaded 事件;如果文檔中包含腳本,則腳本會阻塞文檔的解析,而腳本需要等位於腳本前面的css加載完才能執行。在任何情況下,DOMContentLoaded 的觸發不需要等待圖片等其他資源加載完成。

接下來,我們來說說load,頁面上所有的資源(圖片,音頻,視頻等)被加載以後纔會觸發load事件,簡單來說,頁面的load事件會在DOMContentLoaded被觸發之後才觸發。

我們在 jQuery 中經常使用的 $(document).ready(function() { // ...代碼... }); 其實監聽的就是 DOMContentLoaded 事件,而 $(document).load(function() { // ...代碼... }); 監聽的是 load 事件。在用jquery的時候,我們一般都會將函數調用寫在ready方法內,就是頁面被解析後,我們就可以訪問整個頁面的所有dom元素,可以縮短頁面的可交互時間,提高整個頁面的體驗。

 

在面試的過程中,經常會有人在回答頁面的優化中提到將js放到body標籤底部,原因是因爲瀏覽器生成Dom樹的時候是一行一行讀HTML代碼的,script標籤放在最後面就不會影響前面的頁面的渲染。那麼問題來了,既然Dom樹完全生成好後頁面才能渲染出來,瀏覽器又必須讀完全部HTML才能生成完整的Dom樹,script標籤不放在body底部是不是也一樣,因爲dom樹的生成需要整個文檔解析完畢。

        我們再來看一下chrome在頁面渲染過程中的,綠色標誌線是First Paint的時間。納尼,爲什麼會出現firstpaint,頁面的paint不是在渲染樹生成之後嗎?其實現代瀏覽器爲了更好的用戶體驗,渲染引擎將嘗試儘快在屏幕上顯示的內容。它不會等到所有HTML解析之前開始構建和佈局渲染樹。部分的內容將被解析並顯示。也就是說瀏覽器能夠渲染不完整的dom樹和cssom,儘快的減少白屏的時間。假如我們將js放在header,js將阻塞解析dom,dom的內容會影響到First Paint,導致First Paint延後。所以說我們會將js放在後面,以減少First Paint的時間,但是不會減少DOMContentLoaded被觸發的時間。我們再來看一下chrome在頁面渲染過程中的,綠色標誌線是First Paint的時間。納尼,爲什麼會出現firstpaint,頁面的paint不是在渲染樹生成之後嗎?其實現代瀏覽器爲了更好的用戶體驗,渲染引擎將嘗試儘快在屏幕上顯示的內容。它不會等到所有HTML解析之前開始構建和佈局渲染樹。部分的內容將被解析並顯示。也就是說瀏覽器能夠渲染不完整的dom樹和cssom,儘快的減少白屏的時間。假如我們將js放在header,js將阻塞解析dom,dom的內容會影響到First Paint,導致First Paint延後。所以說我們會將js放在後面,以減少First Paint的時間,但是不會減少DOMContentLoaded被觸發的時間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章