在我们常见的网页当中,我们常看到这样的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://www.windrise.com.cn/demo1.js"></script>
</head>
<body>
<script src="https://www.windrise.com.cn/demo2.js"></script>
<div>
<button>SayHi</button>
</div>
<script src="https://www.windrise.com.cn/demo3.js"></script>
</body>
</html>
在这样的代码中script标签分布在HTML的不同位置,那么按照浏览器的加载顺序,浏览器会先等到demo1.js加载、解析、执行完成后继续加载demo2.js,等待两个JS都执行完成后,浏览器开始呈现页面的内容(HTML标签),等待页面结构加载完成后,最后加载demo3.js的内容。
这样的解析顺序通常会导致浏览器呈现页面的时候出现明显的延迟,导致浏览器窗口出现空白,从而影响用户体验,所以在现代的网页中,我们通常会将<script>引用放在body中页面内容的最后面。这样在网页出现空白的时间就会缩短,从而让用户感觉页面变快了。
<!DOCTYPE html>
...
<body>
<div>
<button>SayHi</button>
</div>
<script src="https://www.windrise.com.cn/demo1.js"></script>
<script src="https://www.windrise.com.cn/demo2.js"></script>
<script src="https://www.windrise.com.cn/demo3.js"></script>
</body>
</html>
延迟和异步
在script标签中定义了两个属性defer和async,他们都会改变script的执行顺序。
- defer
<script src="https://www.windrise.com.cn/demo1.js" defer="defer"></script>
<script src="https://www.windrise.com.cn/demo2.js"defer="defer"></script>
defer会导致demo1和demo2两个脚本延迟到整个页面都解析完成后在执行,他会告诉浏览器立即下载两个脚本,但是延迟执行。同时他也会打破两个脚本按顺序执行的规律,可能会demo2优先执行。 使用defer属性需要注意:
- 加载的文件属于外部脚本
- 页面尽量只包含一个延迟脚本
- async
<script src="https://www.windrise.com.cn/demo1.js" async="async"></script>
<script src="https://www.windrise.com.cn/demo2.js" async ="async"></script>
async会在页面加载其他内容的同时加载这两个脚本,所以为了确保页面正常加载,使用async时要注意以下几点:
- 加载的文件属于外部脚本文件
- 使用async属性的脚本之间互不依赖
- async脚本尽量不要在加载期间修改DOM
元素
在一些浏览器中我们可能会遇到这样的情况,浏览器不支持script脚本或者script脚本被禁用,这种情况,我们会使用到noscript标签来提示用户浏览器需要支持script。
<!DOCTYPE html>
...
<body>
<noscript>
<p>当前浏览器需要支持(开启)JavaScript</p>
</noscript>
</body>
</html>