一.页面中JS的位置
一般来说,一个页面是由HTML+CSS+JavaScript三要素组成。在一个HTML页面中,CSS样式和JavaScript脚本都是通过标签把文件引入到HTML页面中的,我们经常把引入的外部文件都一起放在页面的<head>
标签中。
格式如下:
<!DOCTYPE html>
<html>
<head>
<title>这是一个HTML页面</title>
<!--下面是引入的CSS样式表-->
<link type="text/css" href="sheet1.css"/>
<!--下面是引入的JavaScript文件-->
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<!--这里是页面内容-->
</body>
</html>
二.JS的特性照成的加载问题
- 1.浏览器解析HTML页面是按照从上到下的顺序进行的。
- 2.浏览器加载JavaScript时会产生阻塞效果,在JS文件加载完成前不会同时加载其他文档内容。
- 3.JS文件放在HTML页面头部时,浏览器会首先加载JS文件,此时只有等待浏览器加载完成JS文件才会加载
<body>
中的其它文档内容。 - 4.因为JavaScript是用于页面的交互的,它的使用是基于HTML(内容)和CSS(样式)为前提的。如果页面没有内容,那么JS就毫无意义。
- 5.此时浏览器可能会产生报错,并且当JS文件比较大时,加载时间会比较长,用户打开网页会出现较长时间的延迟现象,也就是白屏。
-
<script>
标签中的async
和defer
属性就是用来解决这个问题的。
三.async和defer的作用和区别
- 1.
<script src="script.js"></script>
<script>
标签中没有使用任何属性,此时就按照浏览器的默认方式,把JS文件加载完成并执行后,再加载页面其它文档内容。 - 2.
<script async src="script.js"></script>
<script>
标签中没有使用了async
属性,此时就告诉浏览器,加载JS文件的时候可以同时加载页面其它内容,(加载时是异步同时进行)但JS文件一旦加载完成就立即执行,不管其他内容有没有加载或解析,执行的时候其它页面内容暂停加载。 - 3.
<script defer src="script.js"></script>
<script>
标签中没有使用了defer
属性,此时就告诉浏览器,加载JS文件的时候可以同时加载页面其它内容,(加载时是异步同时进行)JS文件加载完成后会延迟等待等待其他内容加载或解析完成后才会执行。 -
示意图如下:
蓝色线代表网络读取,红色线代表执行时间,绿色线代表 HTML 解析:
四.其它注意点和执行的顺序
- 1.JS脚本的加载和执行分两个步骤,使用async和defer属性时,加载时都是异步加载,但执行时会有区别。
- 2.async和defer都只适用于外部引入的JS脚本文件。
- 3.有多个JS脚本时执行的顺序优先级:
- 使用async时由于加载和执行连续进行,所以是谁先加载完谁先执行,没有先后顺序。所以使用async时,各JS脚本之间最好不要有任何关联。
- 使用defer时,HTML5规范规定按照JS脚本在HTML页面中的先后顺序执行。但是现实中却并不一定是这样。所以一个HTML页面中最好只有一个使用defer的脚本。
- 最后的解决办法:
把所有JS脚本放在HTML页面内容最后,即</body>
之前。
格式如下:
<!DOCTYPE html>
<html>
<head>
<title>这是一个HTML页面</title>
<!--下面是引入的CSS样式表-->
<link type="text/css" href="sheet1.css"/>
</head>
<body>
<!--这里是页面内容-->
<!--下面是引入的多个JS文件-->
<script type="text/javascript" src="script1.js"></script>
<script type="text/javascript" src="script2.js"></script>
</body>
</html>