背景
测试的目的是为了确认在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的加载顺序,因为可以预加载,但可以保证解析的顺序
参考资料: