可能听说过这样一个约定俗称的开发规范:尽量将JS放在页面的底部。对于不了解的开发人员可能会有一些疑问,为什么要尽量将JS放在页面的底部?

1.为什么要尽量将JS放在页面底部

一个网站为了能给用户有一个极致的体验,会伴随着不断的优化工作。而优化工作中一个比较重要目的就是“快”,让页面更快的呈现给用户。将JS放在页面的底部,也是实现这个目的的手段之一。

2. 为什么JS的位置会影响页面的加载和呈现

JS在浏览器中是以单线程方式执行的,即某个时刻只有特定的代码被执行,其他的代码则会被阻塞。但是Ajax完成后的回调事件,定时触发事件等操作看上去JS执行又是多线程的,这是因为浏览器是是多线程的。有JS引擎线程,事件触发线程,界面渲染线程,HTTP请求线程等。Ajax回调事件,定时触发事件等浏览器事件会放在事件触发线程的执行队列中中,等待当前JS代码执行完毕后再按队列执行。

大家可以执行以下下面这段代码(常见的测试JS单线程执行的代码片段),看看浏览器Console中的输出和自己预想的结果是不是一样。

function printB() {

  console.log('B');

}

function printA () {

console.log('A');

setTimeout(printB, 0);

console.log('C');

}

for (var i = 0; i < 1000; i++) {

   printA();

}

既然JS是单线程的,那么关键点就在于此。当浏览器加载一个页面时,会由相应的线程(也是单线程)按照书写顺序加载资源。对JavaScript文件的加载稍有不同,JS文件加载过程分为两步,第一步和加载CSS文件,图片文件一样发起Http请求下载文件,然后是第二步,由JS线程执行加载的JS

加载JS资源的线程和执行JS的线程不能并行执行,因为JS可以通过操作页面元素来改变页面的渲染,如果并行执行的话,页面可能会混乱。所以JS的加载和执行时一个顺序执行的过程。

因此,如果JS代码的执行时间过长,用户就会很明显的感觉到页面加载比较慢。


但是、放在顶部的JS也不一定会阻塞页面渲染,比如利用jQuery$(doucumen).ready在页面加载完成之后再执行JS,就不会阻塞页面渲染


3. 结论

明白了浏览器的工作方式,就会对那些JS放在页面顶部,那些JS放在页面底部有一个理论上的认识。

4. 参考文章

        浏览器是怎样工作的:渲染引擎,HTML解析