关于script标签所处位置带来的影响
一般script标签会被放在文档的头部(head标签中)或尾部(body结束标签前面)。
浏览器对h5文档的解析时从上到下依次解析的,当发现script的时候,会先下载已经发现的这些script标签对应的js文件,下载完之后才会继续向下解析,如果没有下载完js,那么浏览器就会暂停其他标签的解析工作,并且浏览器是不能同时下载多个js文件的,最多同时下载2个js文件。
<!doctype html>
<html>
<head>
<meta charest="UTF-8">
<title>标题</title>
<script type="text/javascript" src="file1.js"></script>
<script type="text/javascript" src="file2.js"></script>
</head>
<body>
<div>div</div>
</body>
</html>
当把标签放在head标签中时,会先下载script中的js文件,下载完之后浏览器才会继续向下解析,所以有时会导致页面内容呈现滞后,让人感觉页面很卡。
<!doctype html>
<html>
<head>
<meta charest="UTF-8">
<title>标题</title>
</head>
<body>
<div>div</div>
<script type="text/javascript" src="file1.js"></script>
<script type="text/javascript" src="file2.js"></script>
</body>
</html>
当把标签放在尾部时(body结束标签前),确实会先解析完整个页面再进行下载js文件,这样确实能解决放在head标签中带来的页面卡顿问题,但如果遇到一些页面渲染高度依赖于js的网页,那么页面的显示效果就相对不好了,所以将script放在尾部也不是最优解。
最优解就是一边解析html,一边下载js文件,怎么做呢?
<script type="text/javascript" src="file1.js" async></script>
// ==========================================
<script type="text/javascript" src="file2.js" defer></script>
在script标签中有这么两个属性:async
和defer
,可以实现一边解析标签,一边下载js文件,目前80%的浏览器都能够识别出这两个属性。
这两个属性的共同点就是能够使得浏览器一边解析标签一边下载js文件。区别在于:
<script type="text/javascript" src="file1.js" async></script>
<script type="text/javascript" src="file2.js" async></script>
对于async属性,(1)它不保证js加载的顺序,(2)只要加载完js文件之后立马就会执行
<script type="text/javascript" src="file1.js" defer></script>
<script type="text/javascript" src="file2.js" defer></script>
对于defer属性,(1)js文件按加载顺序执行,不过不是加载完立即执行,是谁先加载完到时执行的时候谁就先执行(2)js文件的执行是在文档所有的元素全部解析完成之后才执行
看如下一个图就能基本明白了: