美文网首页前端风暴
把JavaScript文件放在文档的头部还是尾部

把JavaScript文件放在文档的头部还是尾部

作者: dreamapple | 来源:发表于2017-04-16 18:23 被阅读25次

更好阅读体验请前往dreamapple.me

我们今天来聊一聊关于JavaScript文件的引入位置的问题;大家在平时的Web开发中有没有想过这样一个问题,那就是我应该在文档的头部(也就是<head>标签内部里面)引入所需要的JavaScript文件还是应该在尾部(也就是</body>之前)引入所需要的JavaScript文件呢?今天我们就来深入的探究一下这个问题。

首先我们需要了解的一点就是,在浏览器渲染页面之前,它需要通过解析HTML标记然后构建DOM树。在这个过程中,如果解析器遇到了一个脚本(script),它就会停下来,并且执行这个脚本,然后才会继续解析HTML。如果遇到了一个引用外部资源的脚本(script),它就必须停下来等待这个脚本资源的下载,而这个行为会导致一个或者多个的网络往返,并且会延迟页面的首次渲染时间。

还有一点是需要我们注意的,那就是外部引入的脚本(script)会阻塞浏览器的并行下载HTTP/1.1规范表明,浏览器在每个主机下并行下载的组件不超过两个(也就是说,浏览器一次只能够同时从同一个服务器加载两个脚本);如果你网站的图片是通过多个服务器提供的,那么按道理来说,你的网站可以一次并行下载多张图片。但是,当我们网站在加载脚本的时候;浏览器不会再启动任何其它的下载,即使这些组件来自不同的服务器。

看到这里,也许很多开发者都会想:既然把脚本(script)资源放在head里面是个不好的主意,并且可能会阻塞浏览器渲染页面;那我们是不是要把所有的JavaScript文件都放置到文档的底部呢?这个当然也是太过极端了,因为还是有一些情况需要我们在头部引用脚本的;到底是哪些情况需要我们这么做呢,下面我们来看看一些大公司的做法:

google搜索页在head中引入的JavaScript

我们可以看到,这个搜索页面在头部加载了5个JavaScript文件(箭头标注的地方),其中两个JavaScript文件是内联的(inline),另外三个大家可以看到script标签上都添加了async属性,那这个属性是干嘛的呢?我们会在下面解释。

baidu搜索页在head中引入的JavaScript

我们可以看到,百度也在头部引入了一些JavaScript文件,这些文件引入的方式与Google的做法差不多,都在引入外部资源的script标签上添加了async属性,除了第一个JavaScript文件没有那样做。

stackoverflow首页在head中引入的JavaScript weibo首页在head中引入的JavaScript

最后一个是facebook的首页,令我比较出乎意料的是,facebook的首页的头部引入了大量的脚本(script),大家可以看一下截图

facebook首页在head中引入的JavaScript facebook首页在head中引入的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

google搜索页面同步加载的JavaScript

还有的就是单纯的满足自己业务上的一些需求了,比如百度同步加载的那个JavaScript文件:

baidu搜索页面同步加载的JavaScript

所以说,除了上面这些情况外,其它的情况下我们的脚本资源都需要放在文档的底部;当然这里还有一些需要我们注意的问题,首先,脚本加载的顺序很重要,比如如果你的脚本需要使用jQuery库,那么你就应该在加载你的脚本之前先加载jQuery库。其次,有些脚本是需要等到某些元素加载完成之后才可以执行的,那么你可以将你的脚本紧挨在那个元素的后面;还有一些元素是通过脚本动态创建的,所以它们也需要放在合适的位置。比如微博的:

weibo通过脚本动态创建的元素

如果使用过一些框架的脚手架你就会发现,这些框架打包后的那个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文件加载的一些知识,可以看看这篇文章

参考的一些资料:

相关文章

  • 把JavaScript文件放在文档的头部还是尾部

    更好阅读体验请前往dreamapple.me 我们今天来聊一聊关于JavaScript文件的引入位置的问题;大家在...

  • 首屏加载速度优化

    1、JavaScript外联文件引用放在html文档底部;CSS外联文件引用在html文档头部,位于head内; ...

  • 首屏优化方案

    1、JavaScript外联文件引用放在html文档底部;CSS外联文件引用在html文档头部,位于head内;对...

  • 前端优化(首屏优化)

    首屏优化方案 1、JavaScript外联文件引用放在html文档底部;CSS外联文件引用在html文档头部,位于...

  • script标签到底该放在哪里

    一般script标签会被放在头部或尾部。头部就是 里面,尾部一般指 里[4-5]。 将script放在 里,浏览器...

  • vim常用快捷键

    命令模式 gg 跳转到文件头部G 跳转到文件尾部5gg ...

  • HTML5新特性

    一、语义标签 定义了文档的头部区域 (效果同 ) 定义了文档的尾部区域 定义文档的导航 定义文档中的节(s...

  • 暴风游戏实现补充记录

    背景---简单+ 头部---简单 内容---简单 尾部---简单 背景视屏布局脱离文档流;宽高适应屏幕: obje...

  • 《PHPCMS V9 笔记 头部和尾部包含》

    1.主题:头部和尾部包含 引入头部尾部书写样式{template "content","header"}{temp...

  • HTML 5新增标签

    语意标签 : 头部标签 : 导航标签 : 内容标签 : 定义文档某个区域 : 侧边栏标签 : 尾部标签 注意: 这...

网友评论

    本文标题:把JavaScript文件放在文档的头部还是尾部

    本文链接:https://www.haomeiwen.com/subject/ovgaattx.html