本文首發於公衆號:符合預期的CoyPan
內聯JavaScript在如今的前端項目中是比較常見的,好比一些全局函數,全局統計邏輯等,咱們可能會之內聯JavaScript的方式寫在HTML裏。那麼,內聯JavaScript最好應該放在哪裏呢?javascript
首先來看看這個問題:頁面是怎麼渲染的?大體流程以下:css
頁面的渲染是一個複雜的過程,這裏就再也不詳細說了。簡單總結一下,就是使用HTML構建DOM樹,CSS構建CSSOM,二者結合生成Render Tree,而後再進行渲染。html
推薦幾篇值得收藏,反覆閱讀的文章:前端
https://developers.google.com...java
https://developers.google.com...jquery
https://developers.google.com...web
https://developers.google.com...bootstrap
https://developers.google.com...瀏覽器
本文僅僅討論在通常的狀況下,內聯JS應該放在哪一個位置。首先,下面兩點能夠算是【共識】:網絡
JS放在底部是爲了防止阻塞DOM的解析,CSS放在頭部是爲了儘早完成CSSOM的構建,從而儘早paint頁面。下面是一個常見的頁面的HTML代碼:
<html> <head> <link href="xxx.css" rel="stylesheet"> </head> <body> <main>....</main> <script src="xxx.js"></script> </body> </html>
假如咱們有一段內聯的、須要提早加載的、JS統計邏輯代碼,很天然的,會把內聯JS放在head裏。那麼是放在css前面,仍是後面呢?這是本文將要闡述的問題。我作了兩個實驗來看看兩個位置下的頁面渲染流程。爲了突出實驗效果,我模擬的是3g下的網速。
代碼:
<html> <head> <script type="text/javascript"> for (var i = 0; i < 100000000; i++) {} </script> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap-grid.css" rel="stylesheet"> </head> <body> <p>hello word_1</p> <p>hello word_2</p> <p>hello word_3</p> <p>hello word_4</p> <p>hello word_5</p> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script> </body> </html>
timeline以下:
eventlog以下:
從上面兩個圖能夠看到,開始解析HTML後,會開始執行內聯JS,而且發起網絡請求下載CSS和JS文件,當CSS下載完成後,便開始進入渲染。
代碼:
<html> <head> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap-grid.css" rel="stylesheet"> <script type="text/javascript"> console.log(document.getElementById, window); for (var i = 0; i < 100000000; i++) {} </script> </head> <body> <p>hello word_1</p> <p>hello word_2</p> <p>hello word_3</p> <p>hello word_4</p> <p>hello word_5</p> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script> </body> </html>
timeline以下:
eventlog以下:
從上面兩個圖能夠看到,瀏覽器開始解析HTML後,會發起網絡請求下載JS和CSS,當CSS下載完成後,纔會繼續執行內聯JS,頁面的渲染被推遲了,推遲的時間就是內聯JS的執行時間。
對於一些全局函數,全局統計邏輯等,咱們每每會之內聯JS的形式放在HTML內的head裏。此時,最好把內聯JS放在外鏈CSS以前,以提升首屏速度,至少不會拖慢首屏速度。
本文聚焦探索了內聯JS在HTML內的最佳位置。網上關於頁面渲染流程的文章不少,而本身去親自實踐後,才能更好的理解整個渲染流程。符合預期。