背景
測試的目的是為了確認在head與body中js與css的引入的先后順序對頁面性能的影響。由於瀏覽器的更新,本文中的測試需依賴固定的瀏覽器版本。
測試環境
客戶端環境:win7 + chrome 56 + 隱身模式
服務端環境:node v4.6.1 + koa + koa-router + koa-static
工具使用:fiddler
對應版本:

項目結構:

分組測試
1.html + img
1.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> </head> <body> <img src="/img/img1.jpg"> </body> </html>
1.2數據


1.3結論
- html下載完成后,解析並完成構建dom樹之后才會觸發DOMContentLoaded
 - 紅色框表名dom樹解析構建所消耗的時間
 - img的圖片內容顯示與否不會影響到DOMContentLoaded
 - Load的時間包括img的圖片內容下載時間以及render時間
 - 頁面中所有的元素加載完成后才會觸發Load
 - 時間分為兩部分:連接建立時間 + 請求/響應時間,綠色部分為接收到第一個字節所消耗的時間
 
2.HTML + EXTERNAL CSS(HEAD中) + IMG
2.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> <link rel="stylesheet" type="text/css" href="/css/style1.css"> </head> <body> <div class="test">hello test!</div> <img src="/img/img1.jpg"> </body> </html>
2.2數據

當style1.css掛起時:

2.3結論
- head中的css會增加頁面白屏時間,頁面需要等待css下載解析完成,但是在css下載解析過程中,頁面會預加載img等資源
 - 即使css掛起也不影響DOMContentLoaded的觸發(綁定事件需放在css的前面)
 
源碼:
<!DOCTYPE html> <html> <head> <title>test</title> <script type="text/javascript"> var DOMContentLoaded = function() { document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); console.log('okkkk') }; document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); </script> <link rel="stylesheet" type="text/css" href="/css/style1.css"> </head> <body> <div class="test">hello test!</div> <img src="/img/img1.jpg"> </body> </html>
3.HTML + EXTERNAL CSS(HEAD中)+ EXTERNAL JS(HEAD中)+ IMG
3.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> <link rel="stylesheet" type="text/css" href="/css/style1.css"> <script type="text/javascript" src="/js/a.js"></script> </head> <body> <div class="test">hello test!</div> <img src="/img/img1.jpg"> </body> </html>
3.2數據

3.3結論
- head中增加js會增加DOMContentLoaded時間
 - head中的js會增加白屏時間,頁面一直等待js下載執行結束
 - head中的js需要等待css加載解析完成后才會加載執行
 - head中的css會阻塞dom構建,img必須等待直到css下載解析完成
 
4.HTML + EXTERNAL JS(HEAD中) + EXTERNAL CSS(HEAD中) + IMG
4.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> <script type="text/javascript" src="/js/a.js"></script> <link rel="stylesheet" type="text/css" href="/css/style1.css"> </head> <body> <div class="test">hello test!</div> <img src="/img/img1.jpg"> </body> </html>
4.2數據

4.3結論
- head中的js會增加白屏時間,但不影響head中的css下載,js和css可以並行加載
 - head中的css會阻塞dom構建,img必須等待直到css下載解析完成
 
5.HTML + EXTERNAL JS(BODY中)+ EXTERNAL CSS(HEAD中) + IMG
5.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> <link rel="stylesheet" type="text/css" href="/css/style1.css"> </head> <body> <div class="test">hello test!</div> <img src="/img/img1.jpg"> <script type="text/javascript" src="/js/a.js"></script> </body> </html>
5.2數據

5.3結論
- js會增加DOMContentLoaded時間,由於之前頁面已經構建了大部分dom tree,已經渲染,所以此時不會再出現頁面白屏情況
 
6.HTML + EXTERNAL JS(BODY中)+ EXTERNAL CSS(BODY中) + IMG
6.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> </head> <body> <div class="test">hello test!</div> <script type="text/javascript" src="/js/a.js"></script> <link rel="stylesheet" type="text/css" href="/css/style1.css"> <img src="/img/img1.jpg"> <div class="test">hello2 test!</div> </body> </html>
6.2數據
當js掛起時:

當css掛起時:

6.3結論
- body中的css掛起時,不影響DOMContentLoaded的時間,css之后的內容可以預加載,但是只有當css下載解析完成之后才能顯示
 - body中的js掛起時,會影響DOMContentLoaded的時間,js之后資源提前串行加載,直到js下載執行完成后才能顯示
 
7.HTML + EXTERNAL CSS(BODY中) + EXTERNAL JS(BODY中)+ IMG
7.1代碼
<!DOCTYPE html> <html> <head> <title>test</title> </head> <body> <div class="test">hello test!</div> <link rel="stylesheet" type="text/css" href="/css/style1.css"> <script type="text/javascript" src="/js/a.js"></script> <img src="/img/img1.jpg"> <div class="test">hello2 test!</div> </body> </html>
7.2數據
當js掛起時:

當css掛起時:

7.3結論
- 當css置於js前面時,css掛起會導致頁面白屏,需等待css加載完成后才能顯示
 - 當css置於js前面時,js掛起只會影響它之后內容的顯示
 
8.css的加載順序
- 不保證加載css的加載順序,因為可以預加載,但可以保證解析的順序
 
參考資料:
