把JavaScript文件放在文档的头部照样尾部

更好浏览体验,请接见dreamapple.me

我们本日来聊一聊关于JavaScript文件的引入位置的题目;人人在日常平凡的Web开辟中有没有想过如许一个题目,那就是我应该在文档的头部(也就是<head>标签内部内里)引入所须要的JavaScript文件照样应该在尾部(也就是</body>之前)引入所须要的JavaScript文件呢?本日我们就来深切的探讨一下这个题目。

起首我们须要相识的一点就是,在浏览器衬着页面之前,它须要经由历程剖析HTML标记然后构建DOM树。在这个历程当中,假如剖析器遇到了一个剧本(script),它就会停下来,而且实行这个剧本,然后才会继承剖析HTML。假如遇到了一个援用外部资本的剧本(script),它就必需停下来守候这个剧本资本的下载,而这个行动会致使一个或许多个的收集往复,而且会耽误页面的初次衬着时刻。

另有一点是须要我们注重的,那就是外部引入的剧本(script)会壅塞浏览器的并行下载HTTP/1.1范例表明,浏览器在每一个主机下并行下载的组件不凌驾两个(也就是说,浏览器一次只能够同时从同一个服务器加载两个剧本);假如你网站的图片是经由历程多个服务器供应的,那末按原理来讲,你的网站能够一次并行下载多张图片。然则,当我们网站在加载剧本的时刻;浏览器不会再启动任何别的的下载,纵然这些组件来自差别的服务器。

看到这里,或许许多开辟者都会想:既然把剧本(script)资本放在head内里是个不好的主张,而且可能会壅塞浏览器衬着页面;那我们是否是要把一切的JavaScript文件都安排到文档的底部呢?这个固然也是太甚极端了,由于照样有一些状况须要我们在头部援用剧本的;究竟是哪些状况须要我们这么做呢,下面我们来看看一些大公司的做法:

《把JavaScript文件放在文档的头部照样尾部》
我们能够看到,这个搜刮页面在头部加载了5个JavaScript文件(箭头标注的处所),个中两个JavaScript文件是内联的(inline),别的三个人人能够看到script标签上都增加了async属性,那这个属性是干吗的呢?我们会在下面诠释。

《把JavaScript文件放在文档的头部照样尾部》
我们能够看到,百度也在头部引入了一些JavaScript文件,这些文件引入的体式格局与Google的做法差不多,都在引入外部资本的script标签上增加了async属性,除了第一个JavaScript文件没有那样做。

《把JavaScript文件放在文档的头部照样尾部》
《把JavaScript文件放在文档的头部照样尾部》

末了一个是facebook的首页,令我比较出人意料的是,facebook的首页的头部引入了大批的剧本(script),人人能够看一下截图

《把JavaScript文件放在文档的头部照样尾部》
《把JavaScript文件放在文档的头部照样尾部》
不过基本上facebook的script标签上面都增加了async属性,下面我们先来来讲一下script标签上面这个async属性的作用。

这个属性是HTML5给script新增加的属性,而且只适用于外部的JavaScript文件,假如在script标签上增加了这个属性,那末表明这个剧本资本就不再是同步加载的了,而是异步加载的,所以不会壅塞浏览器对页面的衬着。固然这个属性会存在一些兼容性题目,一些浏览器还未完成对这个属性的支撑。

我们能够看到,虽然这些网站大部分的script标签(针对引入的外部文件)都增加了async属性,然则照样有一些script标签没有增加async属性,那就示意这些资本是同步加载实行的,在这里你可能会问,那这些资本为何不运用异步加载呢?缘由很大程度上是由于,这些剧本须要在浏览器衬着页面之前就实行的;比方Yahoo在Best Practices for Speeding Up Your Web Site中就指出,假如你的剧本中运用了document.write在页面中插进去内容的话,那就不能够将这条剧本安排到文档的底部了。相似的另有weibo,weibo的head中也运用了一个要在页面衬着之前就实行的剧本,以下:

<script type="text/javascript">
    try {document.execCommand("BackgroundImageCache", false, true);
        } catch (e) {}
</script>

另有百度首页的head中也有两条须要在页面衬着之前就实行的JavaScript文件:

<script data-compress="strip">
function h(obj){
    obj.style.behavior='url(#default#homepage)';
    var a = obj.setHomePage('//www.baidu.com/');
}
</script>
<script>window._ASYNC_START=new Date().getTime();</script>

另有一些比方Google和Baidu他们搜刮页面同步加载的那些JavaScrip文件一些是为了在页面衬着之前做一些全局的处置惩罚(比方Google)增加了全局变量google

《把JavaScript文件放在文档的头部照样尾部》
另有的就是纯真的满足本身营业上的一些需求了,比方百度同步加载的谁人JavaScript文件:

《把JavaScript文件放在文档的头部照样尾部》

所以说,除了上面这些状况外,别的的状况下我们的剧本资本都须要放在文档的底部;固然这里另有一些须要我们注重的题目,起首,剧本加载的递次很主要,比方假如你的剧本须要运用jQuery库,那末你就应该在加载你的剧本之前先加载jQuery库。其次,有些剧本是须要比及某些元素加载完成以后才能够实行的,那末你能够将你的剧本紧挨在谁人元素的背面;另有一些元素是经由历程剧本动态建立的,所以它们也须要放在适宜的位置。比方微博的:

《把JavaScript文件放在文档的头部照样尾部》

假如运用过一些框架的脚手架你就会发明,这些框架打包后的谁人index.html内里引入的外部JavaScript资本都是放在文档的底部的,而且它们也是根据递次来的,vendor.js文件(项目运用的框架,库打包构成的文件)先引入,然后才是app.js文件(我们写的代码文件打包构成的),这就说清楚明了引入剧本文件的递次也是很主要的。

到现在为止,我们已议论了许多关于把JavaScript文件放在文档的头部照样尾部的缘由,那末下面我们能够总结出一些加载JavaScript文件的最好实践;

  • 关于必需要在DOM加载之前运转的JavaScript剧本,我们须要把这些剧本安排在页面的head中,而不是经由历程外部援用的体式格局,由于外部的援用增加了收集的要求次数;而且我们要确保内敛的这些JavaScript剧本是很小的,最好是紧缩过的,而且实行的速率很快,不会形成浏览器衬着的壅塞。

  • 关于支撑运用script标签的asyncdefer属性的浏览器,我们能够运用这两个属性;个中须要注重的点就是,async示意的意义是异步加载JavaScript文件,它的下载历程能够在HTML的剖析历程当中举行,加载完成以后马上实行这个文件的代码,实行文件代码的历程当中会壅塞HTML的剖析,它不保证文件加载的递次。defer示意的意义是在HTML文档剖析以后在实行加载完成的JavaScript文件,JavaScript文件的下载历程能够在HTML的剖析历程当中举行,它是根据script标签的先后递次来加载文件的。更多细致的诠释能够参考async vs defer attributes

到这里为止,整篇文章就算是完毕了,假如你还想进一步的相识关于JavaScript文件加载的一些学问,能够看看这篇文章

参考的一些材料:

    原文作者:dreamapplehappy
    原文地址: https://segmentfault.com/a/1190000009083504
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞