本文首发于公众号:符合预期的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内的最佳位置。网上关于页面渲染流程的文章不少,而本身去亲自实践后,才能更好的理解整个渲染流程。符合预期。