背景
測試的目的是為了確認在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的加載順序,因為可以預加載,但可以保證解析的順序
參考資料: