<html>
<head>
<title>test</title>
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
我們打開chrome的控制臺查看timeline
由上圖 可得結論
1 圖中藍色透明條標識瀏覽器從發起請求到接收到服務器返回第一個字節的時間,時間還是挺長的,而藍色實體條則為真正的html頁面下載的時間 還是很短的。
2 圖中紅框內的這部分時間則表示瀏覽器從下載完成html之后開始構建dom,當發現一個image標簽時所花費的時間,由此可見dom是順序執行的,當發現image時便立即發起請求,而紫色透明條則是image發起請求時在網絡傳輸時所消耗的時間。
3 圖中timeline藍色豎線所處的時間為domComplete時間,紅色豎線為dom的onload時間,由此可見兩種事件的差異。而瀏覽器構建dom樹所花費的時間可以算出即domComplete時間 減去 html下載完成后的時間大概80ms。
含有css的頁面
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
我們打開chrome的控制臺查看timeline
1 在添加了外部引入css之后,并沒有發現什么異常,但是有一點指的注意,也就是紅色豎線和藍色豎線挨得更進了,這表明domComplete時間必須等待css解析完成,也就是構建dom樹必須等待css解析完成,這也就解釋了下圖
含有javascript和css的頁面
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
<script type="text/javascript" src="H5FullscreenPage.js"></script>
</body>
</html>
我們打開chrome的控制臺查看timeline
1 圖上顯示在引入外部的js文件之后domComplete時間又被延后了,結合上面的renderTree,由于javascript代碼可能會更改css屬性或者是dom結構,所以在形成renderTree之前必須等待javascript解析完成才能接著構建renderTree。
2 將javascript放在head內和body底部的區別也在于此,放在head里面,由于瀏覽器發現head里面有javascript標簽就會暫時停止其他渲染行為,等待javascript下載并執行完成才能接著往下渲染,而這個時候由于在head里面這個時候頁面是白的,如果將javascript放在頁面底部,renderTree已經完成大部分,所以此時頁面有內容呈現,即使遇到javascript阻塞渲染,也不會有白屏出現。
內嵌javascript的頁面
1 圖上可以看到,由于內嵌了javascript,頁面上減少了一個請求,導致html文檔變大,消耗時間增多,但是domComplete時間提升的并不多。
使用async的javascript
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
<script async src="H5FullscreenPage.js" type ="text/javascript" ></script >
</body>
</html>
1 可以看到domComplete時間被大大提前 javascript也沒有阻塞css和body里面img元素的并行下載。
2 使用async標識的script,瀏覽器將異步執行這中script不會阻塞正常的dom渲染,這時html5所支持的屬性,另外defer也可以達到這種效果。
head里面js和css加載的關系
外聯js在css前面
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="H5FullscreenPage.js" type ="text/javascript" ></script >
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="page-animation.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
1 沒有阻止css的并行加載但是影響了body里面img的并行加載
外聯js在css中間
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
<script src="H5FullscreenPage.js" type ="text/javascript" ></script >
<link rel="stylesheet" type="text/css" href="page-animation.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
1 影響了css的并行加載和body里面img的并行加載
外聯js在css最后
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="page-animation.css" media="screen">
<script src="H5FullscreenPage.js" type ="text/javascript" ></script >
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
1 影響了css的并行加載和body里面img的并行加載
內嵌js在css前面
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script type ="text/javascript" >
var f = 1;
f ;
</script >
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="page-animation.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
1 沒有影響css的并行加載也沒有影響body里面img的并行加載
內嵌js在css中間
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
<script type ="text/javascript" >
var f = 1;
f ;
</script >
<link rel="stylesheet" type="text/css" href="page-animation.css" media="screen">
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
1 影響了css的并行加載沒有英雄body里面img的并行加載
內嵌js在css最后
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="page-animation.css" media="screen">
<script type ="text/javascript" >
var f = 1;
f ;
</script >
</head>
<body>
<img src="download-button.png" alt="HTML代碼優化 網頁性能 JavaScript技巧 Javascript">
</body>
</html>
1 影響了css和body里面img的并行加載。
綜上所述:
當瀏覽器從服務器接收到了HTML文檔,并把HTML在內存中轉換成DOM樹,在轉換的過程中如果發現某個節點(node)上引用了CSS或者 IMAGE,就會再發1個request去請求CSS或image,然后繼續執行下面的轉換,而不需要等待request的返回,當request返回 后,只需要把返回的內容放入到DOM樹中對應的位置就OK。但當引用了JS的時候,瀏覽器發送1個js request就會一直等待該request的返回。因為瀏覽器需要1個穩定的DOM樹結構,而JS中很有可能有代碼直接改變了DOM樹結構,瀏覽器為了防止出現JS修改DOM樹,需要重新構建DOM樹的情況,所以 就會阻塞其他的下載和呈現.
這里的結論:
1 在head里面盡量不要引入javascript.
2 如果要引入js 盡量將js內嵌.
3 把內嵌js放在所有css的前面.
后記
1 本次的測試頁面http://1.lvming6816077.sinaapp.com/testaa/demo.html
2 測試所用瀏覽器 chrome
3 參考資料:http://www.zhihu.com/question/20357435/answer/14878543
http://www.haorooms.com/post/web_xnyh_jscss
4 如果有哪里說的不清楚或者錯誤的地方,歡迎留言反饋。